ASP.NET provides mechanisms for storing information for a single user session or across multiple sessions. This is done using the HttpSessionState and HttpApplicationState classes. The Page class has Application and Session attributes to provide access to current objects. The simple way to access them is as following:
if (Session["FirstName"] == null) { LabelFirstName.Text = “FirstName”; } else { LabelFirstName.Text = (string)Session["FirstName"]; } if (Session["LastName"] == null) { LabelLastName.Text = “LastName”; } else { LabelLastName.Text = (string)Session["LastName"]; }
This method has several drawbacks:
- Type Safety: Session contains objects, so you need to cast.
- Null reference: You must check, it might be null
- Variable name: don’t use hard coded strings, beware of typos…
So Lets see the wrapper object and how it solves those issues:
public static class SessionWrapper { private static T GetFromSession<T>(string key) { object obj = HttpContext.Current.Session[key]; if (obj == null) { return default(T); } return (T)obj; } private static void SetInSession<T>(string key, T value) { if (value == null) { HttpContext.Current.Session.Remove(key); } else { HttpContext.Current.Session[key] = value; } } private static T GetFromApplication<T>(string key) { return (T)HttpContext.Current.Application[key]; } private static void SetInApplication<T>(string key, T value) { if (value == null) { HttpContext.Current.Application.Remove(key); } else { HttpContext.Current.Application[key] = value; } } public static string FirstName { get { return GetFromSession<string>(“FirstName”); } set { SetInSession<string>(“FirstName”, value); } } public static string LastName { get { return GetFromSession<string>(“LastName”); } set { SetInSession<string>(“LastName”, value); } } public static User User { get { return GetFromSession<User>(“User”); } set { SetInSession<User>(“User”, value); } } }
It contains a few generic private functions to read and write objects from/to the Session or the Application objects, and public methods to be used from the code to access required properties.Note that the use of HttpContext.Current requires a valid request, or Current might be null!
This wrapper provides a safe typed access from all over the application, one place to define all objects that might be stored in the session. If you want to move objects from the Session to other storing mechanism this would be solved in the wrapper only. The usage is also much easier:
LabelFirstName.Text = SessionWrapper.FirstName; LabelLastName.Text = SessionWrapper.LastName;
Note that you can add any initialization code or default values in the wrapper:
public static string FirstName { get { string firstName = GetFromSession<string>(“FirstName”); if( string.IsNullOrEmpty(firstName)) { firstName = “FirstName”; SetInSession<string>(“FirstName”, firstName); } return firstName; } set { SetInSession<string>(“FirstName”, value); } }

















By AdamJTP on May 7, 2008 | Reply
We use something like this in TeamLive - it also has the advantage that you can deal with session timeouts (and authenication hasn’t timed out) in one place.
An alternative (but not necessarily better) is to use extension methods on HttpSessionState so that new developers (who may be used to dealing with session directly) notice the session facade.
e.g. Once the developer familiar with vanilla Session has typed in “Session.” - the intellisense may prompt them to wonder what the GetFirstName() method does?
e.g.
public static class SessionHelper
{
private const string _sessKeyFirstName = “FirstName”;
///your code but with a “this” param
public static string GetFirstName(this HttpSessionState session)
{
string firstName = GetFromSession(_sessKeyFirstName);
if( string.IsNullOrEmpty(firstName))
{
firstName = _sessKeyFirstName;
SetInSession(_sessKeyFirstName, firstName);
}
return firstName;
}
//all your stuff
private static T GetFromSession(string key)
{
object obj = HttpContext.Current.Session[key];
if (obj == null)
{
return default(T);
}
return (T)obj;
}
private static void SetInSession(string key, T value)
{
if (value == null)
{
HttpContext.Current.Session.Remove(key);
}
else
{
HttpContext.Current.Session[key] = value;
}
}
}
Ideally we’d be able to use extension properties (”.FirstName” (as you’ve done) seems more natural than “.GetFirstName()”) - but I suppose methods have the advantage of being able to take parameters later on - but I guess it’s down to dev team coding preference.
e.g.:
///Optional update if name has been
//updated by different user
//or data feed?
GetFirstName(this HttpSessionState sess,bool refreshSessionFromDb)
{
}
///default case
GetFirstName(this HttpSessionState sess)
{
return sess.GetFirstName(false);
}
By Daniel on May 7, 2008 | Reply
Another option would be to store a single “Plain Old Class Object” in session or application:
internal class MyAppSession
{
public string FirstName{get;set;}
public string LastName{get;set;}
public User User{get; set;}
public static MyAppSession Current
{
get
{
if (HttpContext.Current.Session["MyAppSession"] == null) HttpContext.Current.Session["MyAppSession"] = new MyAppSession();
return (MyAppSession)HttpContext.Current.Session["MyAppSession"];
}
}
}
This makes the properties easier to declare, and you can initialize their values in the constructor.
By Brian Lowry on May 7, 2008 | Reply
While I like the idea, I don’t think its good future-proofing to make the session type-safe in this way. It makes more sense to me to have session accessed from within a domain object. What happens if your requirements change and you can’t use Session anymore? You haven’t successfully abstracted away the location of the stored variable by calling static methods on a SessionWrapper class.
Instead, I would prefer:
internal class Employee
{
public string FirstName { get {…} set {…} }
public string LastName { get {…} set {…} }
And use the get and set to access the session value. Additionally, there should be some form of naming convention for the session key so that there are no collisions… so add in:
public const string FirstNameKey = “Employee.FirstName”;
public const string LastNameKey = “Employee.LastName”;
This keeps you from having to worry about typos and such.
By Brian Lowry on May 7, 2008 | Reply
I also wanted to add that the first part of the SessionWrapper class would be good to use when accessing them in the manner I stated above… i just wouldn’t put FirstName, LastName, etc. as part of the Session class.
By Will on May 7, 2008 | Reply
I use a slightly different pattern:
http://statestreetgang.net/post/2008/01/Generics-and-the-Session-State.aspx
I like passing in a delegate to a method that will store and return the default value. The same pattern can be used for the viewstate, the cache, or any other similar construct.