在控制器和扩展方法中访问ASP.NET MVC Session []数据的建议?

Dav*_*Dev 2 asp.net-mvc

我正在做一个ASP.NET MVC应用程序,我的一些Action方法和其他扩展方法需要访问用户数据.我用来获取用户的代码是:

this.currentUser = (CurrentUser)HttpContext.Session["CurrentUser"];

//and in the extension methods it's:

CurrentUser user = (CurrentUser)HttpContext.Current.Session["CurrentUser"];
Run Code Online (Sandbox Code Playgroud)

在很多我的控制器中,我的很多Action方法都分散了这一行.问题是这使得测试变得困难,并且看起来并不是非常"优雅".

谁能建议一个好的SOLID方法来解决这个问题?

谢谢

戴夫

Luk*_*Led 6

您不应该将用户存储在Session中.通过web.config中的修改或达到内存限制重新启动应用程序时,会很容易丢失会话.这将随机注销用户.

没有理由不将会话用于不同目的(例如将项目存储在篮子中).你可以这样做:

首先我们定义接口:

public interface ISessionWrapper
{
    int SomeInteger { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后我们进行HttpContext实现:

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

然后我们定义基础控制器:

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

    public BaseController()
    {
        SessionWrapper = new HttpContextSessionWrapper();
    }
}
Run Code Online (Sandbox Code Playgroud)

最后:

public ActionResult SomeAction(int myNum)
{           
    SessionWrapper.SomeInteger
}
Run Code Online (Sandbox Code Playgroud)

这将使测试变得简单,因为您可以在控制器测试中使用mock替换ISessionWrapper.