Pregunta

Estoy implimenting mi propia clase Application Context que utiliza el patrón singleton. Quiero guardar mi instancia de ella en HttpContext.Items, ya que estará disponible en todas las partes de la solicitud. He estado leyendo sobre el uso de HttpContext con ASP.NET MVC y uno de los principales dolores es que introduce complejidad pruebas. He intentado hacer la investigación sobre la capacidad de prueba de HttpContext.Items, pero todo lo que puedo encontrar es la materia en la sesión. Una de las únicas cosas que he encontrado es de un capítulo de muestra en el libro ASP.NET MVC 3.5 Profesional en Wrox ( enlace pdf aquí ). En la página 15 se dice lo siguiente:

  

Algo que usted no puede utilizar: HttpContext.Items
  Por encima de esta sección, nos encontramos limpio y dijimos que nos mentimos: HttpContext no se comparte entre ASP.NET MVC y ASP.NET Web Forms. Como resultado de esto, no se puede utilizar la colección HttpContext.Items para almacenar y recuperar bits de datos.
  La razón de esto es porque una vez que redirigir a un controlador, su HttpHandler se convierte en el System.Web.Mvc.MvcHandler, que se crea mediante HttpContextWrapper, que tendrá su propia definición de HttpContext.Current. Por desgracia, durante este apretón de manos, cosas como HttpContext.Items no son transferidos.
  Lo que esto se reduce a que los tipos HttpContext, a pesar de imagen y sonido muy similar, no son lo mismo, y no se puede pasar los datos de esta manera.

Ahora, he intentado probar esto, y por lo que puedo decir, si se redirecciona a otro controlador mediante RedirectToAction, HttpContext.Items no permanecerá. Estoy usando el proyecto de ASP.NET MVC por defecto para probar esto. Lo que he hecho es, añadir este método para Global.asax.cs:

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

Y en HomeController.cs, he cambiado el método de Índice a:

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

Y cambiado el método Acerca de:

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

Al ejecutar la aplicación, la página vuelve a dirigir adecuadamente a / home / Sobre Response.Writes y la correcta cadena "Hola Mundo" establecido en los global.asax.cs.

Por lo tanto, me parece como si estuviera bien no entender lo que el libro lo que significa cuando dicen  "Cosas como HttpContext.Items no se transfieren" O se hace la transferencia de estas cosas y es apropiado el uso de HttpContext.Items.

Si ustedes recomiendan que evito HttpContext.Items, ¿hay otra forma alternativa de almacenar un objeto a través de una consulta a una base por solicitud?

¿Fue útil?

Solución

Su pregunta está pidiendo un par de cosas, pero creo que el punto 1 es la respuesta que está buscando.

  1. Es muy bien utilizar Context.Items para almacenar en caché en una base por solicitud? Si. Si en el proceso, por solicitud, por cada máquina en la granja de servidores web es su criterio a continuación Context.Items le da eso.

  2. Se Context.Items difícil de probar con? En cuanto a la capacidad de prueba, me escondía detrás de una interfaz Context.Items de algún tipo. De esta manera se obtiene capacidades de pruebas de unidad sin tener que hacer referencia a Context.Items directamente. De lo contrario, ¿qué es lo que necesita para poner a prueba sobre Context.Items? Que el marco almacenar y recuperar valores? Mantenga su código ignorantes de System.Web y serás un campista feliz.

  3. Se Context.Items sobrevivir RedirectToAction? No. Su prueba no es válida. Se configura "Hola, mundo" en cada petición web y su prueba abarca dos peticiones web. La primera es cuando se llama a la acción index. La segunda es cuando se llama a la acción RedirectToAction (que es un HTTP 302). Para hacer que falle, establece un nuevo valor en la acción Index y ver si está retenido en el Acerca de acción.

Otros consejos

Utilice el Diccionario TempData, es principalmente para el almacenamiento de objetos entre acciones redirige:

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

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

A continuación, recuperar el valor en su opinión:

<%=ViewData["Test"] %>

Hice una prueba y TempData hace, de hecho, explotar con el estado de sesión deshabilitado. Mi único consejo sería que no almacenar el objeto en sí mismo en los datos temporales, pero almacenar los campos con tipo sencillas como se ha sugerido. Ya que no está serialización de árboles de objetos que no debería ser tan grande de un impacto en el rendimiento se ejecuta fuera de proceso.

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