Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the accepted pattern for implementing Session in ASP.NET MVC sites?

Obviously, the typical WebForms approach won't work. How does one track a user in an MVC world?

like image 785
AngryHacker Avatar asked Mar 05 '10 23:03

AngryHacker


People also ask

Which design pattern is used in ASP.NET MVC?

Model View Controller (MVC) MVC is a design pattern used to decouple user-interface (view), data (model), and application logic (controller). This pattern helps to achieve separation of concerns.

What is session management in ASP.NET MVC?

ASP.NET MVC Session state enables you to store and retrieve values for a user when the user navigatesto other view in an ASP.NET MVC application. Let us take each task one by one, first we will take ViewBag: ViewBag is a property of controllerBase.

What design pattern does ASP.NET use?

ASP.NET MVC 5 for Beginners The MVC design pattern is a popular design pattern for the user interface layer of a software application. In larger applications, you typically combine a model-view-controller UI layer with other design patterns in the application, like data access patterns and messaging patterns.


2 Answers

Session works exactly the same way it worked in Webforms. If you want to store simple information, use forms authentication cookie. If you want to store a content of shopping cart, Session is the place to go. I wrote a blog entry about using Session with ASP.NET:

Lets say that we want to store an integer variable in Session.We will create wrapper around of Session variable that makes it look nicer:

First we define interface:

public interface ISessionWrapper
{
    int SomeInteger { get; set; }
}

Then we make HttpContext implementation:

public class HttpContextSessionWrapper : ISessionWrapper
{
    private T GetFromSession<T>(string key)
    {
        return (T) HttpContext.Current.Session[key];
    }

    private void SetInSession(string key, object value)
    {
        HttpContext.Current.Session[key] = value;
    }

    public int SomeInteger
    {
        get { return GetFromSession<int>("SomeInteger"); }
        set { SetInSession("SomeInteger", value); }
    }
}

GetFromSession and SetInSession are helper method that make taking and setting data in Session easier. SomeInteger property uses these methods.

Then we define our base controller (applicable to ASP.NET MVC):

public class BaseController : Controller
{
    public ISessionWrapper SessionWrapper { get; set; }

    public BaseController()
    {
        SessionWrapper = new HttpContextSessionWrapper();
    }
}

If you want to use Session outside controller, you just create or inject new HttpContextSessionWrapper().

You can replace SessionWrapper with ISessionWrapper mock in Controller tests, so it is not dependent on HttpContext anymore. Session is also more easy to use, because instead of calling (int)Session["SomeInteger"], you call SessionWrapper.SomeInteger. It looks nicer, isn't it?

You may be tempted by idea of creating static class that covers Session object and doesn't require to define any interfaces or initialization in BaseController, but it loses some of advantages, specially when it comes to testing and replacing with other implementation.

like image 61
LukLed Avatar answered Sep 30 '22 15:09

LukLed


Here is a code that I use, just a bit "improved" version of the above version:

private T GetFromSessionStruct<T>(string key, T defaultValue = default(T)) where T : struct 
{
    object obj = HttpContext.Current.Session[key];
    if (obj == null)
    {
        return defaultValue;
    }
    return (T)obj;
}

private T GetFromSession<T>(string key) where T : class
{
    object obj = HttpContext.Current.Session[key];
    return (T)obj;
}

private T GetFromSessionOrDefault<T>(string key, T defaultValue = null) where T : class
{
    object obj = HttpContext.Current.Session[key];
    if (obj == null)
    {
        return defaultValue ?? default(T);
    }
    return (T)obj;
}

private void SetInSession<T>(string key, T value)
{
    if (value == null)
    {
        HttpContext.Current.Session.Remove(key);
    }
    else
    {
        HttpContext.Current.Session[key] = value;
    }
}
like image 44
pajics Avatar answered Sep 30 '22 14:09

pajics