HTTPModule에서 세션 상태에 액세스 할 수 있습니까?


85

내 HTTPModule 내에서 사용자의 세션 변수를 업데이트하여 실제로 할 수 있지만 볼 수있는 것은 불가능합니다.

업데이트 : 내 코드는 현재 OnBeginRequest ()이벤트 핸들러 내에서 실행 중 입니다.

업데이트 : 지금까지받은 조언에 따라 Init ()HTTPModule 의 루틴에 이것을 추가하려고했습니다 .

AddHandler context.PreRequestHandlerExecute, AddressOf OnPreRequestHandlerExecute

그러나 내 OnPreRequestHandlerExecute일상에서 세션 상태는 여전히 사용할 수 없습니다!

감사합니다. 내가 뭔가를 놓친다면 사과드립니다!

답변:


83

ASP.NET 포럼 에서 이것을 찾았습니다 .

using System;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using System.Diagnostics;

// This code demonstrates how to make session state available in HttpModule,
// regardless of requested resource.
// author: Tomasz Jastrzebski

public class MyHttpModule : IHttpModule
{
   public void Init(HttpApplication application)
   {
      application.PostAcquireRequestState += new EventHandler(Application_PostAcquireRequestState);
      application.PostMapRequestHandler += new EventHandler(Application_PostMapRequestHandler);
   }

   void Application_PostMapRequestHandler(object source, EventArgs e)
   {
      HttpApplication app = (HttpApplication)source;

      if (app.Context.Handler is IReadOnlySessionState || app.Context.Handler is IRequiresSessionState) {
         // no need to replace the current handler
         return;
      }

      // swap the current handler
      app.Context.Handler = new MyHttpHandler(app.Context.Handler);
   }

   void Application_PostAcquireRequestState(object source, EventArgs e)
   {
      HttpApplication app = (HttpApplication)source;

      MyHttpHandler resourceHttpHandler = HttpContext.Current.Handler as MyHttpHandler;

      if (resourceHttpHandler != null) {
         // set the original handler back
         HttpContext.Current.Handler = resourceHttpHandler.OriginalHandler;
      }

      // -> at this point session state should be available

      Debug.Assert(app.Session != null, "it did not work :(");
   }

   public void Dispose()
   {

   }

   // a temp handler used to force the SessionStateModule to load session state
   public class MyHttpHandler : IHttpHandler, IRequiresSessionState
   {
      internal readonly IHttpHandler OriginalHandler;

      public MyHttpHandler(IHttpHandler originalHandler)
      {
         OriginalHandler = originalHandler;
      }

      public void ProcessRequest(HttpContext context)
      {
         // do not worry, ProcessRequest() will not be called, but let's be safe
         throw new InvalidOperationException("MyHttpHandler cannot process requests.");
      }

      public bool IsReusable
      {
         // IsReusable must be set to false since class has a member!
         get { return false; }
      }
   }
}

8
! 내가 IRequiresSessionState 구현으로 모듈을 표시하는 경우 MS가이 문제를 해결하려면해야 ..., 난 ... 그걸 얻기 위해 농구를 통해 점프 (참 섹시 코드)를하지 말았어야
BigBlondeViking

6
좋은 코드. 나는 이것이 필요할 것이라고 생각했지만 그렇지 않은 것으로 밝혀졌습니다. 이 코드는 서버를 통과하는 모든 이미지 및 기타 비 페이지 리소스에 대한 세션을로드합니다. 제 경우에는 PostAcquireRequestState 이벤트에서 세션이 null인지 확인하고 그럴 경우 반환합니다.
Abtin Forouzandeh

7
이 코드는 요청 된 리소스가 세션 상태를 처리하지 않는 경우에 유용합니다. 표준 .aspx 페이지의 경우 PostAcquireRequestState 이벤트 처리기에서 세션에 액세스하는 코드를 추가하기 만하면됩니다. 세션 상태가 아직 획득되지 않았기 때문에 BeginRequest 이벤트 핸들러에서 세션 상태를 사용할 수 없습니다.
JCallico 2010-06-18

3
제 경우에는 작동하지 않습니다. "이 컨텍스트에서는 세션 상태를 사용할 수 없습니다."라는 메시지가 표시됩니다. 정적 파일에 액세스하려는 요청이있을 때. 도움이 필요하세요?
maxisam

3
이 작업이 정적 파일에서 작동하도록 preCondition = "managedHandler"(<remove name = "Session"/> <add name = ")를 제거하여 web.config에서 세션 모듈을 다시 등록했습니다. Session "type ="System.Web.SessionState.SessionStateModule "/>)
nlips

39

HTTP 모듈이 세션 상태가 초기화되기 전에 발생 하는 파이프 라인 이벤트 를 처리하지 않는다고 가정하면 HttpContext.Current.Session 이 작동해야합니다 .

EDIT, 주석 설명 후 : BeginRequest 이벤트를 처리 할 때 Session 개체는 ASP.NET 런타임에 의해 아직 초기화되지 않았기 때문에 실제로 여전히 null / Nothing입니다. 이 문제를 해결하기 위해, 이후에 발생하는 이벤트에 처리 코드를 이동 PostAcquireRequestState 처럼 I를 - PreRequestHandlerExecute 모두 낮은 수준의 작업이 거의이 단계에서 수행되는 것처럼, 그 자신을 위해,하지만 당신은 여전히 어떤 정상적인 처리를 선점.


불행히도 HTTPModule에서는 사용할 수 없습니다. "개체 참조가 개체의 인스턴스로 설정되지 않았습니다."
Chris Roberts

'OnBeginRequest'를 처리하고 있습니까?
Chris Roberts

업데이트 해주셔서 감사합니다. 응용 프로그램 수준 이벤트에서 처리하는 경우 HTTPModule을 사용하는 대신 응용 프로그램 수준에서 모든 처리를 수행하지 않는 이유는 무엇입니까?
Chris Roberts

1
PostAcquireRequeststate는 '응용 프로그램 수준 이벤트'가 아닙니다. 예를 들어 HTTP 요청이 웹 서비스 핸들러에 의해 처리되는 경우 HTTP 요청이 여전히 HTTP 모듈에 표시되지만 Global.asax에는 표시되지 않습니다 ...
mdb

이것은 나를 위해 안정적으로 작동하지 않는 것 같습니다. 다음 코드는 종종 '이 컨텍스트에서 세션 상태를 사용할 수 없습니다'예외를 발생시킵니다. 사실, VS 디버거를 매우 훌륭하게 충돌시킵니다. context.PreRequestHandlerExecute + = (sender, args) => Console.Write (((HttpApplication) sender) .Session [ "test"];
cbp

15

액세스 HttpContext.Current.SessionA의는 IHttpModule수행 할 수 있습니다 PreRequestHandlerExecute핸들러입니다.

PreRequestHandlerExecute : "ASP.NET이 이벤트 처리기 (예 : 페이지 또는 XML 웹 서비스) 실행을 시작하기 직전에 발생합니다." 이것은 'aspx'페이지가 제공되기 전에이 이벤트가 실행된다는 것을 의미합니다. '세션 상태'를 사용할 수 있으므로 자신을 녹일 수 있습니다.

예:

public class SessionModule : IHttpModule 
    {
        public void Init(HttpApplication context)
        {
            context.BeginRequest += BeginTransaction;
            context.EndRequest += CommitAndCloseSession;
            context.PreRequestHandlerExecute += PreRequestHandlerExecute;
        }



        public void Dispose() { }

        public void PreRequestHandlerExecute(object sender, EventArgs e)
        {
            var context = ((HttpApplication)sender).Context;
            context.Session["some_sesion"] = new SomeObject();
        }
...
}

나는 이것을 시도하고 실제로 세션을 얻습니다. 그러나 RequestHeader가 완전하지 않은 것 같습니다. 특히 HeaderContentType
Matthias Müller

12

페이지 또는 처리기를 통해 asp.net 요청에 적용하려는 관리되는 응용 프로그램에서 일반적인 기본 HttpModule을 작성하는 경우 세션 생성 후 수명주기에서 이벤트를 사용하고 있는지 확인하기 만하면됩니다. Begin_Request 대신 PreRequestHandlerExecute는 일반적으로 내가가는 곳입니다. mdb는 그의 편집에서 바로 그것을 가지고 있습니다.

원래 질문에 대한 답변으로 나열된 긴 코드 스 니펫이 작동하지만 초기 질문보다 복잡하고 광범위합니다. IRequiresSessionState 인터페이스를 구현할 수있는 ASP.net 처리기가없는 항목에서 콘텐츠가 들어오는 경우를 처리하여 세션 메커니즘을 트리거하여 사용할 수 있도록합니다. (디스크의 정적 gif 파일처럼). 기본적으로 세션을 사용할 수 있도록 인터페이스를 구현하는 더미 핸들러를 설정하는 것입니다.

코드에 대한 세션 만 원하면 모듈에서 처리 할 올바른 이벤트를 선택하기 만하면됩니다.


0

시도해보십시오 : MyHttpModule 클래스에서 다음을 선언하십시오.

private HttpApplication contextapp;

그때:

public void Init(HttpApplication application)
{
     //Must be after AcquireRequestState - the session exist after RequestState
     application.PostAcquireRequestState += new EventHandler(MyNewEvent);
     this.contextapp=application;
}  

따라서 동일한 클래스의 다른 메서드 (이벤트)에서 :

public void MyNewEvent(object sender, EventArgs e)
{
    //A example...
    if(contextoapp.Context.Session != null)
    {
       this.contextapp.Context.Session.Timeout=30;
       System.Diagnostics.Debug.WriteLine("Timeout changed");
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.