Andrei tiene razón: es nulo porque cuando se ejecuta bajo el marco ASP.NET MVC, HttpContext (y por lo tanto HttpContext.Session) no se establece cuando la clase de controlador se construye como cabría esperar, pero se establece ("inyecta") más tarde por la clase ControllerBuilder. Si desea una mejor comprensión del ciclo de vida, puede desplegar el marco ASP.NET MVC (la fuente está disponible) o consultar: esta página
Si necesita acceder a la sesión, una forma sería anular el método "OnActionExecuting" y acceder allí, ya que estará disponible en ese momento.
Sin embargo, como sugiere Andrei, si su código depende de la sesión, entonces podría ser potencialmente difícil escribir pruebas unitarias, por lo que tal vez podría considerar envolver la sesión en una clase auxiliar que luego se puede cambiar por una diferente, no versión web cuando se ejecuta bajo pruebas unitarias, por lo tanto, desacopla su controlador de la web.
Además de las otras respuestas aquí, aunque
Controller.Session
no se completa en el constructor, aún puede acceder a la sesión a través de:System.Web.HttpContext.Current.Session
con la salvedad estándar de que esto reduce potencialmente la capacidad de prueba de su controlador.
fuente
System.Web.HttpContext.Current.Session
también estánull
en el instanciador MVC VS2019.La sesión se inyecta más adelante en el ciclo de vida. ¿Por qué necesitas la sesión en el constructor de todos modos? Si lo necesita para TDD, debe envolver la sesión en un objeto simulado.
fuente
Puede anular el método Initialize para configurar su sesión.
protected override void Initialize(RequestContext requestContext)
fuente
Si está utilizando un contenedor de IoC, intente inyectar y usar el en
HttpSessionStateBase
lugar delSession
objeto:private static Container defaultContainer() { return new Container(ioc => { // session manager setup ioc.For<HttpSessionStateBase>() .Use(ctx => new HttpSessionStateWrapper(HttpContext.Current.Session)); }); }
fuente
Esta respuesta puede ser útil para algunas personas.
Si anulamos el método Initialize, entonces tenemos que inicializar la clase base con el contexto de la solicitud: base.Initialize (requestContext);
protected override void Initialize(RequestContext requestContext) { base.Initialize(requestContext); }
fuente
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
.