Pergunta

Estou implimenting minha própria classe ApplicationContext que utiliza o padrão Singleton. Eu quero armazenar minha instância dele em HttpContext.Items, uma vez que é acessível em todas as partes do pedido. Estive lendo sobre o uso de HttpContext com ASP.NET MVC e uma das principais dores é que ele introduz testar complexidade. Eu tentei fazer a pesquisa sobre a capacidade de teste de HttpContext.Items, mas tudo o que posso encontrar é material na sessão. Uma das únicas coisas que eu encontrei está fora de um capítulo de amostra na Professional ASP.NET MVC 3.5 livro sobre Wrox ( pdf link aqui ). Na página 15 diz o seguinte:

Algo que você não pode usar: HttpContext.Items
Acima nesta seção, chegamos limpo e lhe disse que menti para você: HttpContext não é compartilhada entre ASP.NET MVC e ASP.NET Web Forms. Como resultado disto, você não pode usar a coleção HttpContext.Items para armazenar e recuperar bits de dados.
A razão para isso é porque uma vez que você redirecionar para um controlador, o seu HttpHandler torna-se o System.Web.Mvc.MvcHandler, que é criado usando HttpContextWrapper, que terá a sua própria definição de HttpContext.Current. Infelizmente, durante este aperto de mão, coisas como HttpContext.Items não são transferidos.
O que isto resume-se a que os HttpContext tipos, apesar olhando e soando muito o mesmo, não são o mesmo, e você não pode passar dados desta forma.

Agora, eu tentei testar isso, e, tanto quanto eu posso dizer, se você redirecionar para outro controlador usando RedirectToAction, HttpContext.Items se mantém. Estou usando o projeto ASP.NET MVC padrão para testar isto. O que eu tenho feito é, adicione este método para Global.asax.cs:

protected void Application_BeginRequest()
{
    Context.Items["Test"] = "Hello World";
}

E em HomeController.cs, eu mudei o método de índice para:

public ActionResult Index()
{
    return RedirectToAction("About");
}

E mudou o método Sobre a:

public ActionResult About()
{
    Response.Write(Convert.ToString(HttpContext.Items["Test"]));
    return View();
}

Quando eu executar o aplicativo, a página redireciona corretamente para / Home / About e Response.Writes o "Olá Mundo" set seqüência correta nas global.asax.cs.

Assim, parece-me como se eu ou não estou entendendo o que o livro é o que significa quando dizem "Coisas como HttpContext.Items não são transferidos" ou ele transferir essas coisas e não há problema em usar HttpContext.Items.

Se vocês recomendam que eu evitar HttpContext.Items, existe outra maneira alternativa para armazenar um objeto através de um pedido em uma base per-request?

Foi útil?

Solução

A sua questão é perguntar algumas coisas, mas eu acho item 1 é a resposta que você está procurando.

  1. É bom para usar Context.Items para armazenamento em cache em uma base por solicitação? Sim. Se no processo, por solicitação, por máquina na fazenda web é seus critérios, então Context.Items dá-lhe isso.

  2. É Context.Items difícil teste com? Na medida em que a capacidade de teste, eu iria esconder Context.Items atrás de uma interface de algum tipo. Dessa forma você obtém capacidades de teste de unidade sem ter diretamente para Context.Items referência. Caso contrário, o que você precisa para teste sobre Context.Items? Que o quadro irá armazenar e recuperar valores? Mantenha o seu código ignorante System.Web e você vai ser um campista feliz.

  3. Will Context.Items sobreviver RedirectToAction? Não. O teste é inválido. É a configuração "Olá, mundo" em cada solicitação da web e seus vãos de teste duas solicitações da Web. A primeira é quando a ação Index é chamado. A segunda é quando a ação RedirectToAction é chamado (é um HTTP 302). Para fazê-lo falhar, definir um novo valor na ação Índice e ver se ele está retido no Sobre a ação.

Outras dicas

Use o TempData dicionário, é principalmente para o armazenamento de objetos entre as acções redirecionamentos:

public ActionResult Index()
{
    TempData.Add("Test", "Hello world");
    return RedirectToAction("About");
}

public ActionResult About()
{
    ViewData["Test"] = TempData["Test"];
    return View();
}

Em seguida, recuperar o valor na sua opinião:

<%=ViewData["Test"] %>

Eu fiz um teste e TempData faz, de fato, explodir com o estado da sessão desativado. Meu único conselho seria para não armazenar o próprio objeto em dados temporários, mas armazenar o simples campos digitados como foi sugerido. Desde que você não está serialização árvores objeto não deve ser tão grande de um impacto de desempenho em execução fora de processo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top