为什么使用HttpContext工作的MVC 4会话助手和HttpContextBase不兼容?

时间:2013-04-17 13:18:56

标签: c# asp.net-mvc-4

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

我在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)。 我可以基于HttpContextBase模拟(使用Moq)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类型时会出现问题吗?

1 个答案:

答案 0 :(得分:1)

  

此实现在使用时抛出NullReference异常   以上行动:

     

_sessionHelper = new HttpContextBaseSessionHelper(HttpContext);

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

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

备注你问题中的以下句子:

  

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

您不应该尝试最小化会话变量的使用。您应该尝试从应用程序中完全删除任何ASP.NET Session。