2

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

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

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

更新: MSDN では、通常、Session_OnStartセッション モードが InProc の場合にのみ起動することが明確に示されているため、これを希望どおりに配線するには、何か特別なことを行う必要があります。

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 >

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

4

3 に答える 3

1

編集:質問の要点を少し逃したようです。一部の人にとって興味深いかもしれないという理由だけで、この回答をここに残しておきます。削除する必要があると思われる場合は、お気軽にコメントしてください。

申し訳ありませんが、これは私が言っていることを100%確信していないための回答ですが、コメントするには長すぎます...

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

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

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

<add name="MySession" type="MySessionStateModule" />

次に、global.asaxに必要ですMySession_Start

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

編集して追加:見つけた便利な Web ページの 1 つにリンクすると思いました。http://aspnetresources.com/articles/event_handlers_in_global_asaxでは、global.asax で標準エラー ハンドラーがどのように接続されているかについて説明し、興味深いメソッド HookupEventHandlersForAppplicationAndModules を指摘しました。

于 2010-08-10T15:39:40.387 に答える
1

カスタム SessionStateStores を扱う 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:

    <sessionState mode="Custom" customProvider="MySessionProvider">
        <providers>
            <add name="MySessionProvider" type="WebApplication1.SessionStateProvider"/>
        </providers>
    </sessionState>

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

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

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

于 2010-08-11T09:14:33.177 に答える
0

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

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

于 2010-08-10T15:59:43.653 に答える