2008-10-21 37 views
26

Puede que esta no sea la forma correcta de usar los controladores, pero noté este problema y no encontré una forma de corregirlo.HttpContext en las instancias de los controladores son nulas en ASP.net MVC

public JsonResult SomeControllerAction() { 

    //The current method has the HttpContext just fine 
    bool currentIsNotNull = (this.HttpContext == null); //which is false  

    //creating a new instance of another controller 
    SomeOtherController controller = new SomeOtherController(); 
    bool isNull = (controller.HttpContext == null); // which is true 

    //The actual HttpContext is fine in both 
    bool notNull = (System.Web.HttpContext.Current == null); // which is false   

} 

me he dado cuenta de que el HttpContext en un controlador no es el "real" HttpContext que se encontraría en System.Web.HttpContext.Current.

¿Hay alguna manera de llenar manualmente la HttpContextBase en un controlador? ¿O una mejor manera de crear una instancia de un controlador?

Respuesta

24

Los controladores no están diseñados para crearse manualmente como lo hace. Parece que lo que realmente deberías hacer es poner la lógica reutilizable que tienes en una clase auxiliar.

+1

Brad, ¿tiene algún lugar que pueda ayudar a comprender el diseño de MVC y las mejores prácticas? MVC ha sido genial hasta ahora, pero la mayoría de los ejemplos que he encontrado no son muy complejos. Solo repasan las instancias simples como actualizar un solo registro. – Hugoware

+0

Brad, tengo el mismo problema, y ​​esto también viene de una clase de ayuda, tal como lo recomienda. Probé la solución proporcionada por Hugoware (abajo), y eso lo solucionó. ¿Es esta la manera correcta de hacer esto? –

0

¿Desea utilizar alguna funcionalidad del controlador? ¿O el controlador realiza una acción?

Si es el primero, tal vez sea un código que deba dividirse en otra clase. Si es esto último, puede hacerlo simplemente tener ese controlador hacer una acción específica:

 

return RedirectToAction("SomeAction", "SomeOtherController", new {param1 = "Something" }); 
 
5

El HttpContext, en el ControllerContext es nula, ya que no se establece cuando se crea el controlador. El contructor del controlador no asigna esta propiedad, por lo que será nulo. Normalmente, HttpContext se establece en HttpContext de la clase ControllerBuilder. Los controladores son creados por la clase ControllerBuilder, seguido por DefaultControllerFactory. Cuando desee crear su propia instancia de controlador, puede usar ExecuteMethod del controlador con su propio ControllerContext. No quieres hacer eso es una aplicación real. Cuando obtenga más experiencia con el marco, encontrará el método apropiado para hacer lo que quiera. Cuando necesite la prueba ControllerContext in Unit, puede usar un marco de burla para simular el ControllerContext o puede simularlo en clase.

Puede encontrar un modelo del flujo de solicitudes en asp.net mvc en this blog.

Cuando sea nuevo en Asp.net mvc, vale la pena el esfuerzo de descargar el código fuente y leer un seguimiento de la ruta de cómo se procesa una solicitud.

0

¿Está utilizando una fábrica de controladores? Si es así, ¿cómo está registrando componentes?

Me encontré con este problema donde inadvertidamente agregué una dependencia basada en HttpContext como Singleton, en lugar de Transient en Windsor.

HttpContext era nulo para todos excepto para la primera solicitud. Me llevó un tiempo rastrear ese.

61

Por ahora voy a hacer lo siguiente. Esto parece ser una solución aceptable ...

public new HttpContextBase HttpContext { 
    get { 
     HttpContextWrapper context = 
      new HttpContextWrapper(System.Web.HttpContext.Current); 
     return (HttpContextBase)context;     
    } 
} 

Cuando esto se agrega a una clase de controlador de estos controladores están heredando de.

No estoy seguro si el HttpContext es nulo es el comportamiento deseado, pero esto lo arreglará mientras tanto para mí.

+0

Muchas gracias por descifrar la nueva forma de trabajar entre los dos tipos. Tenía una clase vieja que intentaba usar desde un controlador MVC que consumía un objeto HttpContext.Ahora tengo una clase que consume un objeto HttpContextBase con una sobrecarga de constructor que convertirá entre HttpContext y HttpContextBase usando el constructor HttpContextWrapper que mencionaste. – patridge

+0

Sí, ¡también me gustaría agradecerle por descifrar esto! – Funka

+0

+1 Gran publicación. Estado buscando esto – magnus

Cuestiones relacionadas