Andrei ma rację - ma wartość null, ponieważ podczas uruchamiania w ramach ASP.NET MVC HttpContext (a tym samym HttpContext.Session) nie jest ustawiana, gdy klasa kontrolera jest konstruowana zgodnie z oczekiwaniami, ale jest ustawiana („wstrzykiwana”) później przez klasę ControllerBuilder. Jeśli chcesz lepiej zrozumieć cykl życia, możesz rozwinąć strukturę ASP.NET MVC (źródło jest dostępne) lub zapoznać się z: tą stroną
Jeśli potrzebujesz dostępu do sesji, jednym ze sposobów byłoby zastąpienie metody „OnActionExecuting” i dostęp do niej, ponieważ będzie ona dostępna do tego czasu.
Jednak, jak sugeruje Andrei, jeśli twój kod jest zależny od sesji, wtedy pisanie testów jednostkowych może być trudne, więc być może warto rozważyć umieszczenie sesji w klasie pomocniczej, którą można następnie zamienić na inną, wersja internetowa podczas uruchamiania w ramach testów jednostkowych, dlatego należy odłączyć kontroler od sieci.
Oprócz innych odpowiedzi tutaj, chociaż
Controller.Session
nie jest to wypełnione w konstruktorze, nadal możesz uzyskać dostęp do sesji poprzez:System.Web.HttpContext.Current.Session
ze standardowym zastrzeżeniem, że potencjalnie zmniejsza to testowalność kontrolera.
źródło
System.Web.HttpContext.Current.Session
jest równieżnull
w instancjatorze VS2019 MVC.Sesja jest wstrzykiwana później w cyklu życia. Dlaczego i tak potrzebujesz sesji w konstruktorze? Jeśli potrzebujesz go do TDD, powinieneś zawinąć sesję w obiekt, który można wyrejestrować.
źródło
Możesz zastąpić metodę Initialize, aby ustawić sesję.
protected override void Initialize(RequestContext requestContext)
źródło
Jeśli używasz kontenera IoC, spróbuj wstrzyknąć i użyć
HttpSessionStateBase
zamiastSession
obiektu:private static Container defaultContainer() { return new Container(ioc => { // session manager setup ioc.For<HttpSessionStateBase>() .Use(ctx => new HttpSessionStateWrapper(HttpContext.Current.Session)); }); }
źródło
Ta odpowiedź może być przydatna dla niektórych osób
Jeśli nadpisujemy metodę Initialize, musimy zainicjować klasę bazową z kontekstem żądania: base.Initialize (requestContext);
protected override void Initialize(RequestContext requestContext) { base.Initialize(requestContext); }
źródło
protected override void Initialize(System.Web.Routing.RequestContext requestContext)
.