Pregunta

¿Cuál es la forma más fácil de clonar HttpContext instancia de solicitud actual?

Estoy desarrollando una aplicación en Asp.net MVC v1 . He actualizado las capacidades PartialView regulares que en realidad tienen sub-controladores que actúan de manera muy similar, pero tienen su propio contexto. Cuando se utiliza PartialViews que tiene que rellenar datos de vista para la vista parcial en acción del controlador de la vista principal. He creado mi propia funcionalidad que permite llamar a acciones del controlador desde un punto de vista. De esta manera me sale:

  • No tiene que proporcionar los datos de sub-view en acción del controlador de mi vista principal
  • métodos controlador secundario puede manipular los datos más encapsuladas sin ninguna relación con otros puntos de vista / controladores

El problema es que cada solicitud sub-controlador utiliza HttpContext. Así que cuando me puse un poco de HttpContext.Item en un sub-controlador que realmente llena HttpContext de la solicitud real.

Es por eso que quiero clonar HttpContext. Ya estoy usando:

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

pero esto no establece otra cosa que la solicitud y la respuesta. Pero probablemente también tienen otras propiedades y colecciones ... Al igual período de sesiones, artículos, etc ... usuario.

¿Fue útil?

Solución 2

No es posible

Creo que una clonación de profundidad real no es posible debido a estado de sesión del servidor. La clonación también tendría que clonar este valor, que es el recurso interno específico del servidor web que es intrínsecamente estática y no puede ser clonado. En este caso, un servidor web podría tener varios objetos de sesión, por ejemplo.

Solución
De todas formas. La solución fue establecer valores de contexto adicionales antes de crear instancias de procesamiento de sub-controlador. Una vez finalizado el procesamiento de E invertí los valores originales de nuevo a. Así que en realidad tenía contexto como lo era antes.

Otros consejos

Mientras que el "no es posible" respuesta es correcta, existe una alternativa que es mucho más limpio que escribiendo valores en el contexto actual y luego volver a escribir de nuevo a su estado original. La solución es hacer un nuevo objeto HttpContext por completo que se basa en la URL de su elección.

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

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

El marco ASP.NET MVC hace intencionadamente dependencias a las clases abstractas con todos los miembros virtuales. Eso simplemente dice -. Extensibilidad

Controladores dependen de HttpContextBase, no HttpContext. Tal vez usted puede hacer sus sub-controladores dependen de HttpContextBase también, así que se puede envolver. Sólo mis 2 centavos.

He usado

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

con gran efecto, lo que me permite crear acciones completamente aisladas / escapsulated sin recurrir al código complejo. Esto parecería ofrecer la misma funcionalidad sin la misma complejidad.

Las vistas prestados son vistas parciales estándar y las acciones del controlador como cualquier otro.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top