是否可以复制/克隆 Web 请求的 HttpContext
克隆当前请求的 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?
但这除了请求和响应之外没有设置任何其他内容。但我可能还需要其他属性和集合...比如会话、项目、用户...等。
What's the easiest way to clone current request's HttpContext instance?
I'm developing an app in Asp.net MVC v1. I upgraded the regular PartialView capabilities to actually have sub-controllers that act very similar, but have their own context. When you use PartialViews you have to fill view data for the partial view in your main view's controller action. I created my own functionality that makes it possible to call controller actions from within a view. This way I get:
- I don't have to provide sub-view's data in my main view's controller action
- sub controller methods can manipulate data more encapsulated without any relation to other views/controllers
The problem is that each sub-controller request uses HttpContext. So when I set some HttpContext.Item in a sub-controller it actually populates HttpContext of the actual request.
That's why I want to clone HttpContext. I'm already using:
HttpContext subContext = new HttpContext(request, response);
// what happened to Session, User, Items etc. properties?
but this doesn't set anything else than request and response. But I would probably also need other properties and collections... Like Session, Items, User... etc.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
虽然“不可能”的答案是正确的,但还有一种替代方案比将值写入当前上下文然后重写回其原始状态要干净得多。解决方案是完全基于您选择的 URL 创建一个新的 HttpContext 对象。
参考: https://github.com/maartenba/MvcSiteMapProvider/issues/278#issuecomment -34905271
While the "Not Possible" answer is correct, there is an alternative that is much cleaner than writing values into the current context and then rewriting back to its original state. The solution is to make a new HttpContext object entirely that is based on the URL of your choosing.
Reference: https://github.com/maartenba/MvcSiteMapProvider/issues/278#issuecomment-34905271
对于 ASP.Net Core/.Net 5,以下内容将起作用(基于 SignalR 的 ASP.Net Core 源代码,如果您需要更多功能,只需添加它们)。
For ASP.Net Core/.Net 5 the following will work (based on the ASP.Net Core source code for SignalR, if you need more features just add them).
不可能
我想由于服务器会话状态,实际的深度克隆是不可能的。克隆还必须克隆此值,该值是 Web 服务器特定的内部资源,本质上是静态的且无法克隆。在这种情况下,Web 服务器将具有多个 Session 对象。
解决方法
反正。解决方法是在实例化子控制器处理之前设置额外的上下文值。处理完成后,我将值恢复为原始值。所以我实际上有像以前一样的背景。
Not possible
I guess an actual deep cloning is not possible because of server session state. Cloning would also have to clone this value, which is web server specific internal resource that is intrinsically static and can not be cloned. In this case a web server would have multiple Session objects for instance.
Workaround
Anyway. The workaround was to set additional context values before instantiating sub-controller processing. After processing is finished I reverted values back to original. So I actually had context as it was before.
ASP.NET MVC 框架有意使抽象类的依赖关系与所有成员都是虚拟的。简而言之就是——可扩展性。
控制器依赖于 HttpContextBase,而不是 HttpContext。也许您可以让您的子控制器也依赖于 HttpContextBase,以便您可以包装它。
只是我的2分钱。
The ASP.NET MVC framework intentionally makes dependencies to abstract classes with all members virtual. That simply says - extensibility.
Controllers depend on HttpContextBase, not HttpContext. Perhaps you can make your sub-controllers depend on HttpContextBase too so you can wrap it.
Just my 2 cents.
我的使用
效果非常好,使我能够创建完全隔离/封装的操作,而无需求助于复杂的代码。这似乎提供了相同的功能,但没有相同的复杂性。
渲染的视图是标准的部分视图,控制器操作就像任何其他视图一样。
I've used
to great effect, allowing me to create completely isolated/escapsulated actions without resorting to complex code. This would seem to offer the same functionality without the same complexity.
The rendered views are standard partial views and the controller actions just like any other.