2008-11-09 9 views
77

내 HTTPModule 내에서 사용자의 세션 변수를 업데이트 할 수는 있지만 실제로 볼 수는 없습니다.HTTPModule에서 세션 상태에 액세스 할 수 있습니까?

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

UPDATE : AddHandler context.PreRequestHandlerExecute, AddressOf OnPreRequestHandlerExecute

하지만 내 OnPreRequestHandlerExecute 일상에서

는, 세션 상태는 아직 사용할 수 없습니다 : 조언에 따라 내가 내 HttpModule을에 Init() 루틴이 추가했는데, 지금까지 받았습니다!

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

답변

79

ASP.NET forums에 걸쳐 찾았

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, 
// regradless 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; } 
     } 
    } 
} 
+0

고마워 -이 코드가 트릭을했습니다! –

+7

MS는이 문제를 해결해야합니다! ... 모듈을 IRequiresSessionState를 구현하는 것으로 표시하면, 그것을 얻기 위해 후프를 뛰어 넘을 필요가 없습니다 ... (섹시한 코드 실제로) – BigBlondeViking

+4

좋은 코드. 나는 내가 이것을 필요로 할 것이라고 생각했다. 그러나 그것은 밝혀지지 않았다. 이 코드는 서버를 통과하는 모든 이미지 및 기타 비 페이지 리소스에 대한 세션로드를 종료합니다. 필자의 경우 단순히 PostAcquireRequestState 이벤트에서 세션이 null인지 확인한 후 반환합니다. –

36

HttpContext.Current.Session해야 그냥 직장, 가정하여 HTTP 모듈 댓글에 설명 후, 초기화되는 세션 상태 이전에 발생 pipeline events ...

편집, 처리되지 않은 다음 BeginRequest event 처리, 세션 개체 아직 ASP.NET 런타임에 의해 초기화되지 않았으므로 실제로는 null/Nothing이됩니다. 이 문제를 해결하려면 처리 코드를 PostAcquireRequestState 이후에 발생하는 이벤트로 이동하십시오. 모든 하위 작업은이 단계에서 거의 완료되었으므로 PreRequestHandlerExecute을 좋아합니다.하지만 여전히 정상적인 처리를 선점하고 있습니다.

+0

HTTPModule에서는 "객체 참조가 객체의 인스턴스로 설정되지 않았습니다."는 사용할 수 없습니다. –

+0

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

+0

업데이트 해 주셔서 감사합니다. 응용 프로그램 수준 이벤트에서 처리하면 왜 HTTPModule 대신 응용 프로그램 수준에서 모든 처리를 수행합니까? –

11

당신이 페이지 또는 처리기를 통해 asp.net 요청에 적용 할 관리되는 응용 프로그램의 정상, 기본 HttpModule의를 작성하는 경우, 당신은 단지이 세션 생성 후 라이프 사이클에서 이벤트를 사용하고 있는지 확인하십시오. Begin_Request 대신 PreRequestHandlerExecute가 보통 내가가는 곳입니다. mdb가 편집에 적합합니다.

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

코드에 대한 세션을 원하면 모듈에서 처리 할 올바른 이벤트를 선택하십시오.

12

IHttpModuleHttpContext.Current.Session에 액세스하는 것은 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(); 
     } 
... 
} 
+0

나는 이것을 시도하고, 실제로 세션을 얻는다. 그러나 RequestHeader가 완전하게 존재하지 않는 것처럼 보입니다. 특히 HeaderContentType –

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"); 
    } 
} 
관련 문제