Is it possible to copy / clone an HttpContext web request

What is the easiest way to clone a current instance of an HttpContext request?

I am developing an application in Asp.net MVC v1 . I updated the usual features of PartialView to actually have subcontrollers that are very similar but have their own context. When you use PartialViews, you must fill in the view data for a partial view in the action of the main view controller. I created my own functionality that allows you to call controller actions from a view. This way I get:

  • I do not need to provide sub-task data in the action of my main view controller.
  • subcontroller methods can manipulate data encapsulated without any relation to other views / controllers.

The problem is that every subcontroller request uses an HttpContext. Therefore, when I set some HttpContext.Item object to a sub-controller, it actually populates the HttpContext of the actual request.

This is why I want to clone an HttpContext. I already use:

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

but this sets nothing but a request and a response. But I will probably also need other properties and collections ... As a session, elements, user ... etc.

+4
source share
4 answers

Impossible

I think that actual deep cloning is not possible due to server session state. Cloning would also have to clone this value, which is an internal resource specific to a web server, which is inherently static and cannot be cloned. In this case, the web server will have several session objects, for example.

Bypass
Anyway. The workaround was to set additional context values ​​before creating subcontroller processing. Upon completion of processing, the return values ​​are returned to the original. So I actually had the context, as before.

+2
source

While the answer “Impossible” is correct, there is an alternative that is much cleaner than writing values ​​to the current context and then rewriting back to its original state. The solution is to completely create an HttpContext object based on the URL of your choice.

 // 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... } 

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

+4
source

The ASP.NET MVC framework intentionally makes dependencies abstract classes with all virtual members. It just says extensibility.

Controllers are dependent on HttpContextBase, not HttpContext. Perhaps you can make the subcontrollers also depend on the HttpContextBase so that they can be wrapped. Only my 2 cents.

0
source

I used

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

which allows me to create completely isolated / escapsulated actions without resorting to complex code. It would seem that this gives the same functionality without the same complexity.

Presented representations are standard partial representations and controller actions, like any others.

0
source

All Articles