2

我根据以下示例实现了一个会话助手来保存和检索会话变量:(我尽量减少会话变量的使用) Stackoverflow 问题

我在 Visual Studio 2012 上使用 MVC 4 和目标 .NET 4.5。

我实现了一个设置器。这个使用HttpContextBase(即controller.HttpContext):

public class HttpContextBaseSessionHelper : ISessionHelper
{
    private readonly HttpContextBase _context;

    public HttpContextBaseSessionHelper(HttpContextBase context)
    {
        _context = context;
    }

    public T Get<T>(string key)
    {
        object value = _context.Session[key];
        return value == null ? default(T) : (T)value;
    }

    public void Set<T>(string key, T value)
    {
        _context.Session[key] = value;
    }
}

此实现使用 HttpContext(即 System.Web.HttpContext.Current):

public class HttpContextSessionHelper : ISessionHelper
{
    private readonly HttpContext _context;

    public HttpContextSessionHelper(HttpContext context)
    {
        _context = context;
    }

    public T Get<T>(string key)
    {
        object value = _context.Session[key];
        return value == null ? default(T) : (T)value;
    }

    public void Set<T>(string key, T value)
    {
        _context.Session[key] = value;
    }
}

在控制器中,HttpContext 属性的类型为 HttpContextBase (Controller.HttpContext)。我可以模拟(使用 Moq)基于 HttpContextBase 的 ISessionHelper。

如果设置和检索了正确的值,我使用以下两个控制器操作在正在运行的应用程序(而不是单元测试)中查看:

public ActionResult SessionSet()
{
    _sessionHelper.Set<string>("TestKey", "TestValue");
    ViewBag.SessionValue = (string)HttpContext.Session["TestKey"];
    return View();
}

public ActionResult SessionGet()
{
    HttpContext.Session["TestKey"] = "TestValue";
    ViewBag.SessionValue = _sessionHelper.Get<string>("TestKey");
    return View();
}

使用上述操作时,此实现会引发 NullReference 异常:

_sessionHelper = new HttpContextBaseSessionHelper(HttpContext);

但是这个实现工作得很好:

_sessionHelper = new HttpContextSessionHelper(System.Web.HttpContext.Current);

我的问题是为什么会发生这种情况?使用 HttpContextBase 的实现不应该工作,而使用 HttpContext 的实现不应该看到 Controller.HttpContext 返回一个 HttpContextBase 类型吗?

4

1 回答 1

1

使用上述操作时,此实现会引发 NullReference 异常:

_sessionHelper = new HttpContextBaseSessionHelper(HttpContext);

您已将此代码放在控制器的构造函数中,不是吗?这HttpContext是行不通的,因为该属性在此阶段尚未初始化。Initialize如果要访问任何 HttpContext 相关属性,则应将此代码放入方法中:

protected override void Initialize(RequestContext requestContext)
{
    base.Initialize(requestContext);
    _sessionHelper = new HttpContextBaseSessionHelper(HttpContext);
}

从您的问题中评论以下句子:

我尽量减少会话变量的使用

您不应该尝试尽量减少会话变量的使用。您应该尝试完全摆脱应用程序中的任何 ASP.NET 会话。

于 2013-04-17T13:23:02.623 回答