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.