【问题标题】:Why MVC 4 session helper using HttpContext work and HttpContextBase does not?为什么使用 HttpContext 的 MVC 4 会话助手工作而 HttpContextBase 不工作?
【发布时间】:2013-04-17 21:23:02
【问题描述】:

我根据以下示例实现了一个会话助手来保存和检索会话变量:(我尽量减少会话变量的使用) 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)。 我可以模拟(使用 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 类型吗?

【问题讨论】:

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


    【解决方案1】:

    此实现在使用 以上动作:

    _sessionHelper = new HttpContextBaseSessionHelper(HttpContext);

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

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

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

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

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

    【讨论】:

    • 您将如何在没有会话的情况下管理身份验证/授权?即使您的 SOA 包含用于识别用户的单独签名请求,您仍然需要某种形式的基于会话的 ID 数据来写入请求,不是吗?
    • @Darin 你能发布一些关于如何completely get rid of any ASP.NET Session from your application 的示例或提示吗?
    猜你喜欢
    • 1970-01-01
    • 2016-10-06
    • 1970-01-01
    • 2013-07-01
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    • 2016-05-08
    • 2019-10-03
    相关资源
    最近更新 更多