2


0

カスタムASP.NET SessionStateProviderクラスからSession_OnStartイベントを発生させます

社内開発のカスタムSessionStateProviderクラスを使用するasp.netプロジェクトに取り組んでいます。

明らかに、Session_OnStartイベントは発生していません。 Global.asaxにイベントを処理するコードがあります。 このコードを実行するには、Web.configを変更してデフォルトのSessionStateProviderを使用する必要があります。

カスタムSessionStateProviderクラスを使用しているときにSession_OnStartコードを実行させるにはどうすればよいですか? ソースコードにアクセスできます。

更新:通常、MSDNでは、セッションモードがInProcの場合にのみ `Session_OnStart`が起動するため、これを希望どおりに接続するには特別なことをする必要があります。

web.configでのセッション状態の構成は次のようになります。

< sessionState cookieless="false" regenerateExpiredSessionId="true" mode="Custom"
 customProvider="ProgramSessionStateProvider"
 sessionIDManagerType="SessionIDManager.ProgramSessionIDManager"
sqlConnectionString="SqlSessionServices" cookieName="smartSessionID" >
< providers >
            < add name="ProgramSessionStateProvider"
type="SessionStateProvider.ProgramSessionStateProvider"
connectionStringName="SqlSessionServices" writeExceptionsToEventLog="false" / >
        < /providers >
    < /sessionState >

再度更新:今朝面白いものを見つけました。 Chrisの答えを読んだ後、顧客の SessionStateProvider`のみを使用してみて、カスタムの SessionIDManager`のコードを削除しました。 それをしたら、すぐに Session_OnStart`メソッドが実行されるのを見ることができました。 問題は、カスタムの `SessionStateProvider`がカスタムの SessionIDManager`を必要とすることです。 「Session_OnStart」イベントはどこから発生したのですか? 「SessionStateProvider」ではなく、「SessionIDManager」と関係があるようです。

3 Answer


1


*編集:*質問のポイントを少し見逃したようです。 一部の人にとって興味があるからといって、この答えをここに残しておきます。 ただし、削除する必要があると思われる場合は、コメントしてください。

申し訳ありませんが、これは答えです。私が言っていることは100%確信できませんが、コメントするには長すぎます…​

カスタムセッションモジュールを作成したのか、セッション状態ストアプロバイダーを作成したのかはわかりませんでした。 モジュールを想定していますが、「SessionStateProvider」だけではわかりませんでした…​

web.configに追加されたhttpmoduleは、global.asaxのイベントに接続しようとするプロセスを経ることがわかります。 これを行う方法は、「\ {name} _ \ {event}」または「\ {name} _on \ {event}」の形式のメソッドを探し、その\ {name}はweb.configでモジュールに付けた名前であり、もちろん\ {event}はクラス(つまり開始)のイベントの名前です。

したがって、新しいモジュールが次のように含まれている場合、本質的には:


global.asaxに `MySession_Start`が必要になります

これが役に立つことを願っています。 そうでなくて、以前に試したことのあるものならすべて申し訳ありません。 少しのコードと、あなたがすでに試したもののいくつかのアイデアを与えることをお勧めしますが、それは失敗します。 興味深いコードは、カスタムコードをサイト(web.configの適切な部分)に追加する場所です。また、簡単な形式に簡単にカットできる場合は、セッションクラスのコード(たとえば、短い定数を返し、エラーを示すだけです)。 また、セッション状態を保持しているかどうか(つまり、onstartを呼び出さずに別の形式で動作するかどうか)を示すこともできます。 :)


1


カスタムSessionStateStoreを扱う2番目の回答。 コードを見ると、セッション開始を呼び出さない理由がわからなかったので、準拠しているが機能していない独自のセッション状態プロバイダーを作成して、何が起こっているのかを確認しようとしました。 私のセッション状態プロバイダーでは、global.asaxのSession_startを正常に呼び出しました。 コードをデモの概念実証として含めます。

セッション状態プロバイダー:

namespace WebApplication1
{
    public class SessionStateProvider : System.Web.SessionState.SessionStateStoreProviderBase
    {
        public override SessionStateStoreData CreateNewStoreData(HttpContext context, int timeout)
        {
            ISessionStateItemCollection foo = new SessionStateItemCollection();
            HttpStaticObjectsCollection bar = new HttpStaticObjectsCollection();
            return new SessionStateStoreData(foo, bar, 300);
        }
        public override void CreateUninitializedItem(HttpContext context, string id, int timeout){}
        public override void Dispose() { }
        public override void EndRequest(HttpContext context) { }
        public override SessionStateStoreData GetItem(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
        {
            locked = false;
            lockAge = TimeSpan.FromSeconds(10);
            lockId = new object();
            actions = SessionStateActions.None;
            ISessionStateItemCollection foo = new SessionStateItemCollection();
            HttpStaticObjectsCollection bar = new HttpStaticObjectsCollection();
            return new SessionStateStoreData(foo, bar, 300);
        }
        public override SessionStateStoreData GetItemExclusive(HttpContext context, string id, out bool locked, out TimeSpan lockAge, out object lockId, out SessionStateActions actions)
        {
            locked = false;
            lockAge = TimeSpan.FromSeconds(10);
            lockId = new object();
            actions = SessionStateActions.None;
            ISessionStateItemCollection foo = new SessionStateItemCollection();
            HttpStaticObjectsCollection bar = new HttpStaticObjectsCollection();
            return new SessionStateStoreData(foo, bar, 300);
        }
        internal virtual void Initialize(string name, NameValueCollection config, IPartitionResolver partitionResolver) { }
        public override void InitializeRequest(HttpContext context) { }
        public override void ReleaseItemExclusive(HttpContext context, string id, object lockId) { }
        public override void RemoveItem(HttpContext context, string id, object lockId, SessionStateStoreData item) { }
        public override void ResetItemTimeout(HttpContext context, string id) { }
        public override void SetAndReleaseItemExclusive(HttpContext context, string id, SessionStateStoreData item, object lockId, bool newItem) { }
        public override bool SetItemExpireCallback(SessionStateItemExpireCallback expireCallback){return true;}
    }
}

Global.asax:

    protected void Session_Start(object sender, EventArgs e)
    {
        throw new Exception("It worked!");
    }

web.config:


この投稿のポイントは、提供されたセッション管理モジュールを使用している場合、カスタムプロバイダーを使用している場合でも、session_startイベントを起動する必要があるということです。 おそらく、私のダミーの状態プロバイダーで試して、それがイベントを発生させるかどうかを確認できます。 また、session_onstartの署名が実際に正しいと思いますか? (つまり、パラメーターも(object、eventargs)もありません)。

現在、私たちはこれまでに得たすべての情報が間違った方向に沿っているため、ダフな立場にいます。 sessionstateproviderがsession_startを起動しないか、コードの残りの部分が原因で何かが残っています。 ダミーを使用すると、その質問に答えるのに役立ちます(願っています)。

プロバイダークラスで `CreateNewStoreData`メソッドが実行された直後にsession_startイベントが発生する価値があるので、そこにブレークポイントを入れて、そのメソッドの後にどこに向かうのかを確認できます。


0


Session_OnStartメソッドで具体的に何かをする必要はなく、セッションを初期化するなどの操作を行うことが運用上の目標だと思います。 これが事実であると仮定すると、私はあなたが次のことができると思う:

1)Appication.PostAcquireRequestStateイベントを処理します。 + 2)ハンドラーで、セッションが初期化されているかどうかを確認します-貧しい人の方法はセッションに変数を設定することです-そして適切に動作します。