I am developing an ASP.NET MVC project and want to use strongly-typed session objects. I have implemented the following Controller-derived class to expose this object:
public class StrongController<_T> : Controller
where _T : new()
{
public _T SessionObject
{
get
{
if (Session[typeof(_T).FullName] == null)
{
_T newsession = new _T();
Session[typeof(_T).FullName] = newsession;
return newsession;
}
else
return (_T)Session[typeof(_T).FullName];
}
}
}
This allows me to define a session object for each controller, which is in line with the concept of controller isolation. Is there a better/more "correct" way, perhaps something that is officially supported by Microsoft?
TempData is ideal for short-lived things like displaying validation errors or other messages that we don't need to persist for longer than a single request. Session is ideal choice when we need to persist data for extended periods of time i.e. it is used to store data which is required throughout user session.
It is perfectly OK to use sessions in ASP.NET MVC, especially in the shopping cart scenario of yours.
This way other objects won't have access to this object (e.g. ActionFilter). I do it like this:
public interface IUserDataStorage<T>
{
T Access { get; set; }
}
public class HttpUserDataStorage<T>: IUserDataStorage<T>
where T : class
{
public T Access
{
get { return HttpContext.Current.Session[typeof(T).FullName] as T; }
set { HttpContext.Current.Session[typeof(T).FullName] = value; }
}
}
Then, I can either inject IUserDataStorage into controller's constructor, or use ServiceLocator.Current.GetInstance(typeof(IUserDataStorage<T>)) inside ActionFilter.
public class MyController: Controller
{
// automatically passed by IoC container
public MyController(IUserDataStorage<MyObject> objectData)
{
}
}
Of course for cases when all controllers need this (e.g. ICurrentUser) you may want to use property injection instead.
This might be better for what you want. I would just create an extension method that can access your session. The added benefit to the extension method is that you no longer have to inherit from a controller, or have to inject a dependency that really isn't necessary to begin with.
public static class SessionExtensions {
public static T Get<T>(this HttpSessionBase session, string key) {
var result;
if (session.TryGetValue(key, out result))
{
return (T)result;
}
// or throw an exception, whatever you want.
return default(T);
}
}
public class HomeController : Controller {
public ActionResult Index() {
//....
var candy = Session.Get<Candy>("chocolate");
return View();
}
}
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