views:

1475

answers:

6

We can access session data in controllers and views like this:

Session["SessionKey1"]

How do you access Session values from a class other than a controller or view?

+4  A: 

I'd use dependency injection and pass the instance of the HttpContext (or just the session) to the class that needs access to the Session. The other alternative is to reference HttpContext.Current, but that will make it harder to test since it's a static object.

   public ActionResult MyAction()
   {

       var foo = new Foo( this.HttpContext );
       ...
   }


   public class Foo
   {
        private HttpContextBase Context { get; set; }

        public Foo( HttpContextBase context )
        {
            this.Context = context;
        }

        public void Bar()
        {
            var value = this.Context.Session["barKey"];
            ...
        }
   }
tvanfosson
Thank you for responding. Looks like there are a few Dependency Injection frameworks. Which DI framework do you suggest? Is there a must read articles on DI? :)
xraminx
this seems overly complicated for what the original poster was asking for.
Nick Berardi
@xraminx -- don't confuse what I'm suggesting with a DI framework. I'm talking about using DI, the pattern, not a framework. The idea is that you pass an instance of the dependency to the class rather than have it create one or use a static instance. Much easier to unit test via mocking.
tvanfosson
Heh heh, I've never quite 'got' the term dependency injection until I read that answer, +1
pauliephonic
A: 

Haven't done it myself, but this sample from Chad Meyer's blog might help (from this post: http://www.chadmyers.com/Blog/archive/2007/11/30/asp.net-webforms-and-mvc-in-the-same-project.aspx)

[ControllerAction]
public void Edit(int id)
{
    IHttpSessionState session = HttpContext.Session;

    if (session["LoggedIn"] == null || ((bool)session["LoggedIn"] != true))
        RenderView("NotLoggedIn");

    Product p = SomeFancyDataAccess.GetProductByID(id);

    RenderView("Edit", p);
}
Chuck
+3  A: 

Ditto to tvanfosson, and in addition, check out this post by Fredrik Kalseth which shows how to do exactly that but allows you to test without having to actually have an HTTPContext.

jlembke
A: 

You just need to call it through the HttpContext like so:

HttpContext.Current.Session["MyValue"] = "Something";
Nick Berardi
@Nick -- try unit testing by mocking up the static HttpContext and see how easy that is. I've done it -- no thanks.
tvanfosson
FYI -- there's a reason why the framework designers introduced HttpSessionStateBase and HttpContextBase into the newer versions of the framework and why you can change the HttpContext in a controller by modifying the controller context. It makes it much easier to unit test your actions.
tvanfosson
Original poster never asked about testing. He asked how he could access the session.
Nick Berardi
A: 

I would also wrap all session variables into a single class file. That way you can use intelliSense to select them. This cuts down on the number of paces in code where you need to specify the "strings" for the session.

Tony Borf
A: 

Here is my version of a solution for this problem. Notice that I also use a dependency injection as well, the only major difference is that the "session" object is accessed threw a Singleton

private iSession _Session;

private iSession InternalSession
{
    get
    {

        if (_Session == null)
        {                
           _Session = new SessionDecorator(this.Session);
        }
        return _Session;
    }
}

Here is the SessionDecorator class, which uses a Decorator pattern to wrap the session around an interface :

public class SessionDecorator : iSession
{
    private HttpSessionStateBase _Session;
    private const string SESSIONKEY1= "SESSIONKEY1";
    private const string SESSIONKEY2= "SESSIONKEY2";

    public SessionDecorator(HttpSessionStateBase session)
    {
        _Session = session;
    }

    int iSession.AValue
    {
           get
        {
            return _Session[SESSIONKEY1] == null ? 1 : Convert.ToInt32(_Session[SESSIONKEY1]);
        }
        set
        {
            _Session[SESSIONKEY1] = value;
        }
    }

    int iSession.AnotherValue
    {
        get
        {
            return _Session[SESSIONKEY2] == null ? 0 : Convert.ToInt32(_Session[SESSIONKEY2]);
        }
        set
        {
            _Session[SESSIONKEY2] = value;
        }
    }
}`

Hope this helps :)

Smoothcity