克隆当前请求的 HttpContext 实例的最简单方法是什么?

我正在开发一个应用程序 Asp.net MVC v1. 。我升级了常规 PartialView 功能,使其实际上具有行为非常相似的子控制器,但具有自己的上下文。当您使用 PartialViews 时,您必须在主视图的控制器操作中填充部分视图的视图数据。我创建了自己的功能,可以从视图内调用控制器操作。这样我得到:

  • 我不必在主视图的控制器操作中提供子视图的数据
  • 子控制器方法可以更封装地操作数据,与其他视图/控制器没有任何关系

问题是每个子控制器请求都使用HttpContext。因此,当我在子控制器中设置一些 HttpContext.Item 时,它实际上会填充实际请求的 HttpContext。

这就是为什么我想克隆 HttpContext。我已经在使用:

HttpContext subContext = new HttpContext(request, response);
// what happened to Session, User, Items etc. properties?

但这除了请求和响应之外没有设置任何其他内容。但我可能还需要其他属性和收藏......如会话、项目、用户...ETC。

有帮助吗?

解决方案 2

不可能

我想由于服务器会话状态,实际的深度克隆是不可能的。克隆还必须克隆此值,该值是 Web 服务器特定的内部资源,本质上是静态的且无法克隆。在这种情况下,Web 服务器将具有多个 Session 对象。

解决方法
反正。解决方法是在实例化子控制器处理之前设置额外的上下文值。处理完成后,我将值恢复为原始值。所以我实际上有像以前一样的背景。

其他提示

虽然“不可能”的答案是正确的,但还有一种替代方案比将值写入当前上下文然后重写回其原始状态要干净得多。解决方案是完全基于您选择的 URL 创建一个新的 HttpContext 对象。

// A new request/response is constructed to using a new URL.
// The new response is using a StreamWriter with null stream as a backing stream 
// which doesn't consume resources

using (var nullWriter = new StreamWriter(Stream.Null))
{
    var newRequestUri = new Uri("http://www.somewhere.com/some-resource/");
    var newRequest = new HttpRequest("", newRequestUri.ToString(), newRequestUri.Query);

    var newResponse = new HttpResponse(nullWriter);
    var newContext = new HttpContextWrapper(new HttpContext(newRequest, newResponse));

    // Work with the new context here before it is disposed...
} 

参考: https://github.com/maartenba/MvcSiteMapProvider/issues/278#issuecomment-34905271

ASP.NET MVC 框架有意使抽象类的依赖关系与所有成员都是虚拟的。简而言之就是——可扩展性。

控制器依赖于 HttpContextBase,而不是 HttpContext。也许您可以让您的子控制器也依赖于 HttpContextBase,以便您可以包装它。只是我的2分钱。

我用过

<% Html.RenderAction("Action", "Controller"); %>

效果很好,使我能够创建完全隔离/封装的操作,而无需求助于复杂的代码。这似乎提供了相同的功能,但没有相同的复杂性。

渲染的视图是标准的部分视图,控制器操作就像任何其他视图一样。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top