做强类型ASP.NET MVC会话的更好方法

Dav*_*fer 20 c# asp.net-mvc session strong-typing

我正在开发一个ASP.NET MVC项目,并希望使用强类型的会话对象.我已实现以下Controller派生类来公开此对象:

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];
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

这允许我为每个控制器定义一个会话对象,这符合控制器隔离的概念.是否有更好/更"正确"的方式,也许是微软官方支持的方式?

que*_*en3 18

这样,其他对象将无法访问此对象(例如ActionFilter).我是这样做的:

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; }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,我可以将IUserDataStorage注入到控制器的构造函数中,或者在ActionFilter中使用ServiceLocator.Current.GetInstance(typeof(IUserDataStorage <T>)).

public class MyController: Controller
{
   // automatically passed by IoC container
   public MyController(IUserDataStorage<MyObject> objectData)
   {
   }
}
Run Code Online (Sandbox Code Playgroud)

当然,对于所有控制器都需要这种情况的情况(例如ICurrentUser),您可能希望使用属性注入.


Kha*_*meh 5

这可能对你想要的更好.我只想创建一个可以访问会话的扩展方法.扩展方法的附加好处是您不再需要从控制器继承,或者必须注入一个真正不必开始的依赖项.

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(); 
    }

}
Run Code Online (Sandbox Code Playgroud)