在ASP.NET MVC站点中实现Session的可接受模式是什么?

Ang*_*ker 5 c# asp.net-mvc session .net-3.5

显然,典型的WebForms方法是行不通的.如何跟踪MVC世界中的用户?

Luk*_*Led 24

Session的工作方式与Webforms中的工作方式完全相同.如果要存储简单信息,请使用表单身份验证cookie.如果您想存储购物车的内容,可以选择Session.我写了一篇关于在ASP.NET中使用Session的博客文章:

让我们说我们想在Session中存储一个整数变量.我们将创建Session变量的包装器,使其看起来更好:

首先我们定义接口:

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)

GetFromSession和SetInSession是辅助方法,可以更轻松地在Session中获取和设置数据.SomeInteger属性使用这些方法.

然后我们定义我们的基本控制器(适用于ASP.NET MVC):

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

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

如果要使用Session outside controller,只需创建或注入新的HttpContextSessionWrapper()即可.

您可以在Controller测试中将SessionWrapper替换为ISessionWrapper mock,因此它不再依赖于HttpContext.Session也更容易使用,因为您调用SessionWrapper.SomeInteger而不是调用(int)Session ["SomeInteger"].它看起来更好,不是吗?

您可能会想到创建覆盖Session对象的静态类,并且不需要在BaseController中定义任何接口或初始化,但它会失去一些优势,特别是在测试和替换其他实现时.

  • 因为:1. var cart =(List <CartItems>)HttpContext.Current.Session [key]看起来很可怕,SessionWrapper.CartItems看起来不错.2.为ISessionWrapper编写测试更容易.ISessionWrapper可以轻松模拟,并替换为各种测试场景的内容.它失去了依赖性.如果我想使用另一个存储而不是Session,我只需创建其他ISessionWrapper实现.您必须替换使用Session的每个控制器中的代码. (8认同)