我正在使用我自己的使用单例模式的 ApplicationContext 类。我想将它的实例存储在 HttpContext.Items 中,因为它可以在请求的所有部分中访问。我一直在阅读有关将 HttpContext 与 ASP.NET MVC 结合使用的信息,主要的痛点之一是它引入了测试复杂性。我试过研究 HttpContext.Items 的可测试性,但我能找到的只是 Session 上的东西。我发现的唯一内容之一是关于 Wrox 的 Professional ASP.NET 3.5 MVC 书的示例章节(此处为 pdf 链接)。在第 15 页上,它说:
你不能使用的东西:HttpContext.Items
在本节的上面,我们坦白告诉你我们对你撒了谎:HttpContext 不在 ASP.NET MVC 和 ASP.NET Web 窗体之间共享。因此,您不能使用 HttpContext.Items 集合来存储和检索数据位。
这样做的原因是因为一旦你重定向到一个Controller,你的HttpHandler就变成了System.Web.Mvc.MvcHandler,它是使用HttpContextWrapper创建的,它会有自己的HttpContext.Current定义。不幸的是,在这个握手过程中,像 HttpContext.Items 这样的东西没有被传输。
这归结为 HttpContext 类型,尽管看起来和听起来非常相似,但并不相同,并且您不能以这种方式传递数据。
现在,我已经尝试对此进行测试,据我所知,如果您使用 RedirectToAction 重定向到另一个控制器,HttpContext.Items 确实会保留。我正在使用默认的 ASP.NET MVC 项目来测试它。我所做的是,将此方法添加到 Global.asax.cs:
protected void Application_BeginRequest()
{
Context.Items["Test"] = "Hello World";
}
在 HomeController.cs 中,我将 Index 方法更改为:
public ActionResult Index()
{
return RedirectToAction("About");
}
并将 About 方法更改为:
public ActionResult About()
{
Response.Write(Convert.ToString(HttpContext.Items["Test"]));
return View();
}
当我运行应用程序时,页面会正确重定向到 /Home/About 和 Response。写入 global.asax.cs 中设置的正确“Hello World”字符串。
因此,在我看来,当他们说“未传输 HttpContext.Items 之类的东西”时,我似乎要么不理解这本书的含义,要么它确实传输了这些东西,并且可以使用 HttpContext.Items。
如果你们建议我避免使用 HttpContext.Items,是否有另一种替代方法可以在每个请求的基础上跨请求存储对象?