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
MSはこれを修正する必要があります!...モジュールをIRequiresSessionStateを実装するものとしてマークした場合、それを取得するためにフープをジャンプする必要はありません...(確かにセクシーなコード)
BigBlondeViking 2009

6
素敵なコード。これが必要だと思いましたが、そうではありませんでした。このコードは、サーバーを通過するすべての画像およびその他の非ページリソースのセッションをロードすることになります。私の場合、PostAcquireRequestStateイベントでセッションがnullかどうかを確認し、nullの場合は戻ります。
Abtin Forouzandeh 2010

7
このコードは、要求されたリソースがセッション状態を処理しない場合に役立ちます。標準の.aspxページの場合は、PostAcquireRequestStateイベントハンドラーでセッションにアクセスするコードを追加するだけです。セッション状態はまだ取得されていないため、BeginRequestイベントハンドラーではセッション状態を使用できません。
JCallico 2010年

3
私の場合は機能しません。「このコンテキストではセッション状態は使用できません」というメッセージが表示されました。静的ファイルにアクセスしようとする要求がある場合。何か助けはありますか?
maxisam 2013

3
これを静的ファイルで機能させるには、さらに、preCondition = "managedHandler"(<remove name = "Session" /> <add name = ")を削除して、セッションモジュールを(web.configで)再登録する必要があります。 Session "type =" System.Web.SessionState.SessionStateModule "/>)
nlips 2014

39

HTTPモジュールが、セッション状態が初期化される前に発生するパイプラインイベントを処理していないと仮定すると、HttpContext.Current.Session正常に機能するはずです...

コメントで明確にした後の編集:BeginRequestイベントを処理するとき、SessionオブジェクトはASP.NETランタイムによってまだ初期化されていないため、実際にはnull / Nothingのままです。この問題を回避するには、後に発生するイベントへのあなたの処理コードを移動PostAcquireRequestStateように私を- PreRequestHandlerExecuteすべての低レベルの作業はかなりこの段階で行われているように、その自分のために、あなたはまだ任意の通常の処理を横取り。


残念ながら、これはHTTPModuleでは使用できません-「オブジェクト参照がオブジェクトのインスタンスに設定されていません」。
クリス・ロバーツ

'OnBeginRequest'を処理していますか?
クリス・ロバーツ

更新していただきありがとうございます。アプリケーションレベルのイベントで処理する場合、HTTPModuleを使用する代わりに、アプリケーションレベルですべての処理を実行しないのはなぜですか?
クリス・ロバーツ

1
PostAcquireRequeststate「とは、アプリケーション・レベルのイベント」ではない:HTTPリクエストがWebサービス・ハンドラによって処理されている場合、たとえば、あなたはまだ...あなたのHTTPモジュールではなく、Global.asaxの中でそれを参照してくださいよ
MDB

これは私にとって確実に機能していないようです。次のコードは、しばしば例外を引き起こします 'セッション状態はこのコンテキストでは利用できません'。実際、VSデバッガーは非常に見事にクラッシュします。context.PreRequestHandlerExecute + =(sender、args)=> Console.Write(((HttpApplication)sender).Session ["test"];
cbp

15

アクセスHttpContext.Current.SessionIHttpModuleで行うことができPreRequestHandlerExecuteハンドラ。

PreRequestHandlerExecute: "ASP.NETがイベントハンドラー(ページやXML Webサービスなど)の実行を開始する直前に発生します。" これは、「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 especally、そうです
マティアス・ミュラー

12

ページまたはハンドラーを介してasp.net要求に適用する、管理対象アプリケーションで通常の基本的なHttpModuleを作成している場合は、セッション作成後のライフサイクルでイベントを使用していることを確認する必要があります。通常、Begin_Requestの代わりにPreRequestHandlerExecuteが使用されます。mdbは彼の編集でそれを正しく持っています。

質問への回答として最初にリストされた長いコードスニペットは機能しますが、最初の質問よりも複雑で幅広いものです。これは、コンテンツがASP.netハンドラーを使用できないものからのものであり、IRequiresSessionStateインターフェイスを実装できる場合に対処します。これにより、セッションメカニズムがトリガーされて使用可能になります。(ディスク上の静的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.