Obviously, the typical WebForms approach won't work. How does one track a user in an MVC world?
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.
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.
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.
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.
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;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With