ASP.Net MVC 컨트롤러 생성자의 세션 null


88

컨트롤러 생성자에서 세션이 null 인 이유는 무엇입니까? Action 메서드에서 액세스 할 수 있습니다. 아마도 MVC 라우팅 프레임 워크는 컨트롤러를 새로 만드는 일을 담당하기 때문에 해당 시점에서 세션을 (재) 인스턴스화하지 않았습니다.

이것이 의도적으로 설계된 것인지, 그렇다면 그 이유를 아는 사람이 있습니까?

[Lazy Loading Pattern을 사용하여 문제를 피할 수있었습니다.]

답변:


79

Andrei가 맞습니다. ASP.NET MVC 프레임 워크에서 실행할 때 컨트롤러 클래스가 예상대로 구성 될 때 HttpContext (및 따라서 HttpContext.Session)가 설정되지 않았지만 나중에 설정 ( "주입 됨")되기 때문에 null입니다. ControllerBuilder 클래스에 의해. 수명주기를 더 잘 이해하려면 ASP.NET MVC 프레임 워크 (소스 사용 가능)를 풀다운하거나이 페이지를 참조하십시오.

세션에 액세스해야하는 경우 한 가지 방법은 "OnActionExecuting"메서드를 재정의하고 해당 시간에 사용할 수 있으므로 거기에서 액세스하는 것입니다.

그러나 Andrei가 제안했듯이 코드가 Session에 의존하는 경우 잠재적으로 단위 테스트를 작성하기 어려울 수 있으므로 다른 비로 교체 할 수있는 도우미 클래스로 Session을 래핑하는 것을 고려할 수 있습니다. 단위 테스트에서 실행할 때 웹 버전이므로 웹에서 컨트롤러를 분리합니다.


3
이것이 HttpContext에 대한 적절한 진술인지 확신하지 못합니다. 실제로 전체 흐름이 시작될 때 바로 구성되었습니다. beletsky.net/2011/06/inside-aspnet-mvc-route-to-mvchanlder.html에서 자세한 흐름에 대해 조금 읽을 수 있습니다. 또는 리플렉터를 사용하여 httpContext가 인스턴스화되었을 때 자신을 찾을 수 있습니다. .cs.
Alexey Shcherbak 2012-08-06

@AlexeyShcherbak 이미 생성되었을 수 있습니다. OP는 MVC 컨트롤러의 Session 속성에 설정되었는지 여부에 관한 것입니다. 즉, 공개 HttpSessionStateBase Session {get; } on System.Web.Mvc.Controller 이것들은 다른 것들입니다.
MemeDeveloper

61

여기에있는 다른 답변 외에도 Controller.Session생성자에는 채워지지 않지만 다음을 통해 세션에 액세스 할 수 있습니다.

System.Web.HttpContext.Current.Session

이것은 잠재적으로 컨트롤러의 테스트 가능성을 감소 시킨다는 표준 경고와 함께.


3
이 두 세션 속성의 유형은 각각 다르므로 세션 상태 자체에 대한 참조를 유지하려는 경우 중요 할 수 있습니다.
BrianCooksey 2013 년

@BrianCooksey 무엇이 다른가요?
MichaelMao

1
Controller.Session은 System.Web.HttpSessionStateBase 유형 ( msdn.microsoft.com/en-us/library/… 참조 )이지만 System.Web.HttpContext.Current.Session은 System.Web.SessionState.HttpSessionState 유형입니다 ( msdn 참조). .microsoft.com / en-us / library /… )
BrianCooksey

오래된 대답이지만 VS2019 MVC 인스턴스 System.Web.HttpContext.Current.Session에도 있다고 말하고 싶었습니다 null.
jp2code

11

세션은 라이프 사이클의 후반부에 삽입됩니다. 어쨌든 생성자에 세션이 필요한 이유는 무엇입니까? TDD에 필요한 경우 세션을 mockable 객체로 래핑해야합니다.


1
Andrei Rinea에 덧붙여, 이것은 그가 언급 한 기술의 구체적인 예입니다 : iridescence.no/post/…
murki

4
이전에 저장된 세션 정보에 액세스 할 수 있도록 생성자 중에 세션에 액세스하고 싶습니다. 예, OnActionExecuting 메서드를 재정의 할 수 있지만 이것은 확실히 우아한 솔루션이 아닙니다.
Chris Arnold

8

Initialize 메서드를 재정 의하여 세션을 설정할 수 있습니다.

protected override void Initialize(RequestContext requestContext)

2

IoC 컨테이너를 사용하는 HttpSessionStateBase경우 Session개체 대신 다음을 삽입하고 사용하십시오 .

private static Container defaultContainer()
{
    return new Container(ioc =>
    {
        // session manager setup
        ioc.For<HttpSessionStateBase>()
           .Use(ctx => new HttpSessionStateWrapper(HttpContext.Current.Session)); 
    });
}

2

이 답변은 일부 사람들에게 유용 할 수 있습니다.

Initialize 메서드를 재정의하면 요청 컨텍스트로 기본 클래스를 초기화해야합니다. base.Initialize (requestContext);

protected override void Initialize(RequestContext requestContext)
        {
            base.Initialize(requestContext);
           

        }

유능한. 메서드 시그니처 protected override void Initialize(System.Web.Routing.RequestContext requestContext).
Martin_W
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.