É possível copiar / clone HttpContext de uma solicitação da web
-
13-09-2019 - |
Pergunta
O que é a maneira mais fácil de instância HttpContext clone do pedido atual?
Estou desenvolvendo um aplicativo em Asp.net MVC v1 . I atualizado as capacidades regulares PartialView para realmente ter sub-controladores que atuam muito semelhante, mas tem seu próprio contexto. Quando você usa PartialViews você tem que preencher os dados vista para a vista parcial na ação do controlador a sua principal da vista. Eu criei minha própria funcionalidade que torna possível para chamar ações do controlador a partir de um ponto de vista. Desta forma, eu recebo:
- Eu não tenho para fornecer dados de sub-view na ação do controlador minha principal de vista ??li>
- métodos do controlador sub pode manipular os dados mais encapsulados sem qualquer relação a outros pontos de vista / controladores
O problema é que cada pedido sub-controlador usa HttpContext. Então, quando eu definir algumas HttpContext.Item em uma sub-controlador que realmente preenche HttpContext da solicitação atual.
É por isso que eu quero clone HttpContext. Eu já estou usando:
HttpContext subContext = new HttpContext(request, response);
// what happened to Session, User, Items etc. properties?
mas isso não define qualquer outra coisa do que pedido e resposta. Mas eu provavelmente também precisa de outras propriedades e coleções ... Como Session, itens de Usuários ... etc.
Solução 2
Não possível
Eu acho que uma clonagem profunda real não é possível por causa do estado de sessão do servidor. A clonagem também teria de clonar este valor, que é recurso interno específico servidor web que é intrinsecamente estática e não pode ser clonado. Neste caso, um servidor web teria objetos múltiplos Session por exemplo.
Solução
De qualquer forma. A solução foi para definir os valores de contexto adicionais antes de instanciar processamento sub-controlador. Após o processamento é terminado eu revertido valores de volta ao original. Então, eu realmente tive contexto como era antes.
Outras dicas
Enquanto a resposta "não é possível" é correto, não é uma alternativa que é muito mais limpo do que escrever valores no contexto atual e, em seguida, reescrever volta ao seu estado original. A solução é fazer um novo objeto HttpContext inteiramente que é baseado no URL de sua escolha.
// 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...
}
Referência: https://github.com/maartenba/MvcSiteMapProvider/issues/ 278 # issuecomment-34905271
O framework ASP.NET MVC intencionalmente faz dependências de classes abstratas com todos os membros virtuais. Isso simplesmente diz -. Extensibilidade
Controllers dependem HttpContextBase, não HttpContext. Talvez você possa fazer suas sub-controladores dependem HttpContextBase também, então você pode envolvê-lo. Apenas meus 2 centavos.
Eu usei
<% Html.RenderAction("Action", "Controller"); %>
com grande efeito, permitindo-me para criar completamente isoladas / ações escapsulated sem recorrer ao código complexo. Isto parece oferecer a mesma funcionalidade sem a mesma complexidade.
As opiniões prestados são vistas parciais padrão e as ações do controlador como qualquer outro.