Strongly Typed Session Variables in ASP.NET MVC

This post was originally going to be a comment on Jarret@Work's blog post about "Using Extension Methods for Session Values", but I decided to make a full blog post out of it.  Jarret employed extension methods such Bar()/SetBar() and Foo()/SetFoo() to have strongly-typed session data.  While his method certainly works, I've taken a different approach that I think is a bit more flexible and reads better.

Like Jarret, I maintain a "SessionKeys" class – there is no easier way to ask for trouble than using a magic string buried across 4 or 5 web pages.  But I expose my session data in a base class that all controllers in my application derive from.  Here's a sample from my post on unit testing ASP.NET MVC controllers:

public abstract class BaseController : Controller
{
    protected SpeakerInfo SpeakerInfo
    {
        get
        {
            var info = Session[SessionKeys.SpeakerInfoKey] as SpeakerInfo;
            if( info == null)
            {
                info = new SpeakerInfo();
            }
 
            return info;
        }
        set
        {
            Session[SessionKeys.SpeakerInfoKey] = value;
        }
    }
}

Now all of my controllers inherit from BaseController and they can easily access the data stored in the Session by utilizing the SpeakerInfo property.  I like this over Jarret's implementation for two reasons:

  1. Properties make the code more readable than get/set methods (in my opinion).
  2. I can change where/how SpeakerInfo is stored without affecting the rest of my code (perhaps to use a database instead of Session).

To be fair, #2 is also possible with Jarret's implementation.  He can change the code in his get/set methods.  But his code would still read "Session.Bar()" and "Session.SetBar()" when (if the implementation was changed to use a database), it wouldn't really be using the Session.

Technorati Tags:

6 Comments

  • Why can't we just have extension properties and be done with it? Some things, like session, are begging to be dynamic. I didn't like the parens in my own post (which you've fixed - methods should be methods, properties should be properties), and I didn't like putting on another wrapper (my previous post) for strong typing (MVC already wraps HttpSessionState with a new HttpSessionStateWrapper from the Abstractions library).

  • Thanks for the article, very nice code...

  • Thanks Patrick,

    This will help us

  • Bill,

    I love your idea of the SpeakerContext object that is injected via an IOC container! This also removes the one big thing I do NOT like about my implementation is that it relies on inheritance.

    Perhaps an ISpeakerContext interface that I can mock during testing, and then create a SessionSpeakerContext implementation for production (which can be easily swapped out later by a different implementation without changing any code).

    Off to code...

  • Denny/Jeff Klawiter/dario-g,

    All of those rely too much on knowing the location of where the data is stored. I prefer to abstract that.

  • Instead of:

    var info = Session[SessionKeys.SpeakerInfoKey] as SpeakerInfo;

    if(info == null)
    {
    info = new SpeakerInfo();
    }

    return info;

    Try:

    return Session[SessionKeys.SpeakerInfoKey] as SpeakerInfo
    ?? new SpeakerInfo();

    :-)

Comments have been disabled for this content.