Pregunta

Estoy trabajando en un proyecto asp.net que utiliza una clase personalizada SessionStateProvider de desarrollo propio.

Evidentemente, el evento no se Session_OnStart disparando. Tengo código en Global.asax para controlar el evento. Sólo puedo obtener este código para ejecutar cambiando el Web.config para usar la SessionStateProvider por defecto.

¿Qué debo hacer para que mi código Session_OnStart ejecutar cuando estoy usando una clase SessionStateProvider personalizada? Tengo acceso al código fuente.

Actualizar : Se dice claramente en MSDN que normalmente, Session_OnStart sólo se desencadena cuando el modo de sesión es InProc, así que voy a tener que hacer algo especial para conseguir este cableada como yo quiero a él.

Mi configuración de estado de sesión en las miradas web.config como esto:

< 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 de nuevo : He encontrado algo interesante esta mañana. Después de leer la respuesta de Chris, he intentado usar sólo el SessionStateProvider cliente y quité el código para el SessionIDManager personalizado. Una vez que lo hice, yo era capaz de ver inmediatamente el método Session_OnStart ejecutar. El problema es que mi SessionStateProvider encargo requiere a SessionIDManager personalizado. ¿Dónde está exactamente el evento disparado desde Session_OnStart? Se parece que tiene que ver con el SessionIDManager, no el SessionStateProvider.

¿Fue útil?

Solución

Una segunda respuesta con el tráfico de SessionStateStores personalizados. En mirar el código pude ver ninguna razón por la que no llamaría inicio de la sesión, así que traté de crear mi propia compatible pero proveedor de estado de sesión no funcional para ver lo que estaba pasando. Con el profesional de estado de sesión se llama el Session_Start in fine Global.asax. Incluyo mi código como una prueba de demostración del concepto:

Proveedor de estado de sesión:

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>

El punto de este post es sobre todo para decir que si está utilizando el módulo de gestión de sesiones proporcionado, incluso con un proveedor personalizado que aún debe disparar el evento session_start. Tal vez se puede tratar con el profesional del estado simulado y ver si eso fuegos su acontecimiento. También supongo que la firma de su Session_OnStart es realmente correcto? (Es decir, no hay Paramaters o (objeto, EventArgs)).

Actualmente estamos en una posición Duff porque toda la información que tenemos hasta ahora es a lo largo de las líneas equivocadas. Ahora nos queda ya sea algo acerca de su sessionstateprovider está causando el session_start no un incendio o algo sobre el resto de su código es. Usando mi maniquí debería ayudarnos a responder a esa pregunta (espero).

Por lo que su valor caso session_start debe ser despedido justo después del método CreateNewStoreData se ha quedado en su clase de proveedor para que pueda intentar poner en un punto de interrupción y no sólo ver donde lo hace la cabeza para después de ese método.

Otros consejos

Editar: Parece que echaba de menos el punto ligeramente sobre la cuestión. Voy a dejar esta respuesta aquí, aunque sólo porque puede ser de interés para algunos. Siéntase libre de comentar si cree que debería suprimirse sin embargo.

En este momento se trata de una respuesta, ya que no estoy 100% seguro de lo que estoy diciendo, pero se hacía demasiado largo para ser un comentario ...

Yo no estaba seguro de si hubiera creado un módulo de sesión personalizado o jsut un proveedor de almacén de estado de sesión. Estoy asumiendo que el módulo pero no estaba segura de sólo "SessionStateProvider" ...

A partir de lo que puedo decir cualquier HttpModule añadido en el web.config pasará a través de un proceso de tratar de conectar a los acontecimientos en el Global.asax. La forma de implementar esto parece ser mediante la búsqueda de métodos de la forma "{nombre} _ {evento}" o "{nombre} _ON {evento}" y el cableado hacia arriba donde que que { nombre} es el nombre que le dio el módulo en su web.config y {evento}, por supuesto, es el nombre del evento en la clase (es decir, empezar).

Así que, en esencia, si el nuevo módulo se incluye como esto:

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

entonces usted querría en su global.asax MySession_Start

Espero que esto ayude. Lo siento si no lo hace y es todo cosas que he probado antes. Yo sugeriría que da un poco de código y algunas ideas de lo que ya han probado y que no logra sin embargo. Código que podría ser interesante es donde se agrega el código personalizado en el sitio (es decir, la parte apropiada de web.config) y tal vez algo de código en su clase de sesión si puede ser fácilmente reducido a una forma trivial (por ejemplo, un proveedor de sesión que sólo devuelve una constante podría ser corto y demostrar su error). También alguna indicación de si se mantiene el estado de sesión o no (es decir, ¿funciona además no forma llamando OnStart) sería bueno. :)

Editar para añadir: que pensé enlace Una de las páginas web útiles que me encontré. http://aspnetresources.com/articles/event_handlers_in_global_asax habla de cómo los gestores de errores estándar están cableados en el Global.asax y me señaló la HookupEventHandlersForAppplicationAndModules interesante método que me dio una idea de cómo algo de esto podría estar trabajando.

Me voy a adivinar el objetivo operativo es hacer algo como, por ejemplo, inicializar la sesión en lugar de tener que hacer algo específicamente en el método Session_OnStart. Suponiendo que este es el caso, creo que se puede hacer lo siguiente:

1) Controle el evento Appication.PostAcquireRequestState.
2) En manipulador, comprobar si se inicia la sesión - camino del hombre pobre es establecer una variable en la sesión -. A continuación, actuar apropiadamente

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top