Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

strongly typed sessions in asp.net

Pardon me if this question has already been asked. HttpContext.Current.Session["key"] returns an object and we would have to cast it to that particular Type before we could use it. I was looking at various implementations of typed sessions

http://www.codeproject.com/KB/aspnet/typedsessionstate.aspx http://weblogs.asp.net/cstewart/archive/2008/01/09/strongly-typed-session-in-asp-net.aspx http://geekswithblogs.net/dlussier/archive/2007/12/24/117961.aspx

and I felt that we needed to add some more code (correct me if I was wrong) to the SessionManager if we wanted to add a new Type of object into session, either as a method or as a separate wrapper. I thought we could use generics

public static class SessionManager<T> where T:class
 {
  public void SetSession(string key,object objToStore)
  {
   HttpContext.Current.Session[key] = objToStore;
  }

  public T GetSession(string key)
  {
   return HttpContext.Current.Session[key] as T;
  }

 }
  • Is there any inherent advantage in using

    SessionManager<ClassType>.GetSession("sessionString")

than using

HttpContext.Current.Session["sessionString"] as ClassType
  • I was also thinking it would be nice to have something like

SessionManager["sessionString"] = objToStoreInSession, but found that a static class cannot have an indexer. Is there any other way to achieve this ?

  • My thought was create a SessionObject which would store the Type and the object, then add this object to Session (using a SessionManager), with the key. When retrieving, cast all objects to SessionObject ,get the type (say t) and the Object (say obj) and cast obj as t and return it.

    public class SessionObject { public Type type {get;set;} public Object obj{get;set;}
    }

this would not work as well (as the return signature would be the same, but the return types will be different).

Is there any other elegant way of saving/retrieving objects in session in a more type safe way

like image 852
ram Avatar asked Jan 09 '10 22:01

ram


4 Answers

For a very clean, maintainable, and slick way of dealing with Session, look at this post. You'll be surprised how simple it can be.

like image 156
TheObjectGuy Avatar answered Nov 06 '22 18:11

TheObjectGuy


A downside of the technique is that consuming code needs to be aware of what keys to use for storage and retrieval. This can be error prone, as the key needs to be exactly correct, or else you risk storing in the wrong place, or getting a null value back.

I actually use the strong-typed variation, since I know what I need to have in the session, and can thus set up the wrapping class to suit. I've rather have the extra code in the session class, and not have to worry about the key strings anywhere else.

like image 44
Grant Palin Avatar answered Nov 06 '22 18:11

Grant Palin


You can simply use a singleton pattern for your session object. That way you can model your entire session from a single composite structure object. This post refers to what I'm talking about and discusses the Session object as a weakly typed object: http://allthingscs.blogspot.com/2011/03/documenting-software-architectural.html

like image 42
allthingscs Avatar answered Nov 06 '22 20:11

allthingscs


Actually, if you were looking to type objects, place the type at the method level like:

public T GetValue<T>(string sessionKey)
{

}

Class level is more if you have the same object in session, but session can expand to multiple types. I don't know that I would worry about controlling the session; I would just let it do what it's done for a while, and simply provide a means to extract and save information in a more strongly-typed fashion (at least to the consumer).

Yes, indexes wouldn't work; you could create it as an instance instead, and make it static by:

public class SessionManager
{
    private static SessionManager _instance = null;


    public static SessionManager Create()
    {
       if (_instance != null)
           return _instance;

       //Should use a lock when creating the instance
       //create object for _instance

       return _instance;
    }

    public object this[string key] { get { .. } }
}

And so this is the static factory implementation, but it also maintains a single point of contact via a static reference to the session manager class internally. Each method in sessionmanager could wrap the existing ASP.NET session, or use your own internal storage.

like image 31
Brian Mains Avatar answered Nov 06 '22 18:11

Brian Mains