asp.neteventssessionglobal-asaxsession-state-provider

Raise Session_OnStart event from custom ASP.NET SessionStateProvider class


I'm working on an asp.net project that uses an in-house developed custom SessionStateProvider class.

Evidently, the Session_OnStart event is not firing. I have code in Global.asax to handle the event. I can only get this code to execute by changing the Web.config to use the default SessionStateProvider.

What must I do to make my Session_OnStart code execute when I'm using a custom SessionStateProvider class? I have access to the source code.

Update: It clearly says on MSDN that ordinarily, Session_OnStart only fires when the Session mode is InProc, so I'm going to have to do something special to get this wired up the way I want it.

My session state configuration in web.config looks like this:

< 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 >

Update again: I found something interesting this morning. After reading Chris's answer, I tried using just the customer SessionStateProvider and removed the code for the custom SessionIDManager. Once I did that, I was immediately able to see the Session_OnStart method execute. The problem is, my custom SessionStateProvider requires a custom SessionIDManager. Where exactly is the Session_OnStart event fired from? It looks like it has to do with the SessionIDManager, not the SessionStateProvider.


Solution

  • A second answer dealing with custom SessionStateStores. On looking at the code I could see no reason why it wouldn't call session start so I tried to create my own compliant but non-functional session state provider to see what was going on. With my session state provider it called the Session_start in global.asax fine. I include my code as a demo proof of concept:

    Session State Provider:

    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>
    

    The point of this post is mainly to say that if you are using the provided session management module, even with a custom provider it should still fire off the session_start event. Perhaps you can try with my dummy state provider and see if that fires off your event. Also I assume that the signature of your session_onstart is actually correct? (ie no paramaters or (object,eventargs) ).

    Currently we are at a duff position because all the information we have so far is along the wrong lines. We are now left with either something about your sessionstateprovider is causing the session_start not to fire or something about the rest of your code is. Using my dummy should help us answer that question (I hope).

    For what its worth the session_start event should get fired just after the CreateNewStoreData method has run in your provider class so you can try putting in a breakpoint there and just seeing where it does head to after that method.