Pergunta

Estou trabalhando em um projeto ASP.NET que usa uma classe de sessão personalizada de sessão personalizada desenvolvida interna.

Evidentemente, o evento session_onstart não está disparando. Eu tenho código no global.asax para lidar com o evento. Só posso fazer com que esse código seja executado alterando o web.config para usar o SessionStateProvider padrão.

O que devo fazer para fazer meu código session_onstart executar quando estou usando uma classe SessionStateProvider personalizada? Tenho acesso ao código -fonte.

Atualizar: Diz claramente no msdn que normalmente, Session_OnStart Somente dispara quando o modo de sessão é inproc, então vou ter que fazer algo especial para obter isso conectado do jeito que eu quero.

A configuração do estado da minha sessão no web.config se parece com o seguinte:

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

Atualizar novamente: Encontrei algo interessante esta manhã. Depois de ler a resposta de Chris, tentei usar apenas o cliente SessionStateProvider e removeu o código para o costume SessionIDManager. Depois que fiz isso, pude imediatamente ver o Session_OnStart Método Execute. O problema é que meu costume SessionStateProvider requer um costume SessionIDManager. Onde exatamente está o Session_OnStart Evento demitido? Parece que tem a ver com o SessionIDManager, não o SessionStateProvider.

Foi útil?

Solução

Uma segunda resposta que lida com sessões personalizadas. Ao analisar o código, não pude ver nenhuma razão para que ele não ligasse para o início da sessão, então tentei criar meu próprio provedor de estados de sessão compatível, mas não funcional, para ver o que estava acontecendo. Com o meu provedor estadual de sessão, ele chamou de session_start em global.asax fino. Eu incluo meu código como uma prova de conceito de demonstração:

Provedor estadual de sessão:

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>

O objetivo desta postagem é principalmente dizer que, se você estiver usando o módulo de gerenciamento de sessão fornecido, mesmo com um provedor personalizado, ele ainda deve disparar o evento session_start. Talvez você possa tentar com meu provedor de estado fictício e ver se isso dispara seu evento. Também presumo que a assinatura da sua session_onstart esteja realmente correta? (ou seja, sem parâmetros ou (objeto, EventArgs)).

Atualmente, estamos em uma posição de duff, porque todas as informações que temos até agora estão nas linhas erradas. Agora ficamos com algo sobre o seu SessionStateProvider está fazendo com que o session_start não atire ou algo sobre o restante do seu código. Usar meu manequim deve nos ajudar a responder a essa pergunta (espero).

Pelo que vale o evento de session_start deve ser demitido logo após o CreateNewStoreData O método foi executado na sua aula de provedores para que você possa tentar colocar um ponto de interrupção lá e apenas ver para onde ele vai depois desse método.

Outras dicas

Editar: Parece que eu perdi o ponto da pergunta um pouco. Vou deixar essa resposta aqui, apenas porque pode ser de interesse para alguns. Sinta -se à vontade para comentar se você acha que deve ser excluído.

Desculpe, isso é uma resposta, já que não tenho 100% de certeza do que estou dizendo, mas ficou muito tempo para ser um comentário ...

Eu não tinha certeza se você havia criado um módulo de sessão personalizado ou o provedor de lojas estaduais de uma sessão. Estou assumindo o módulo, mas eu não tinha certeza de apenas "sessionStateProvider" ...

Pelo que posso dizer, qualquer httpmodule adicionado no web.config passará por um processo de tentativa de se conectar a eventos no global.asax. A maneira como isso faz isso parece ser procurando métodos da forma "{name} _ {event}" ou "{name} _on {event}" e ligando -os onde eu acho Esse {nome} é o nome que você deu ao módulo em seu web.config e {event} é claro que é o nome do evento na classe (ou seja, start).

Então, em essência, se seu novo módulo estiver incluído como este:

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

então você gostaria de seu global.asax MySession_Start

Eu espero que isso ajude. Desculpe se não é e tudo o que você tentou antes. Eu sugiro dar um pouco de código e algumas idéias do que você já tentou e isso falha. Código que pode ser interessante é onde você adiciona seu código personalizado ao site (ou seja, a parte apropriada do web.config) e talvez algum código na sua classe de sessão, se ele puder ser facilmente reduzido para um formulário trivial (por exemplo, um provedor de sessão que Apenas retorna uma constante pode ser curta e demonstrar seu erro). Além disso, alguma indicação de se mantém o estado da sessão ou não (ou seja, funciona à parte não ligando para o início) seria bom. :)

Editar para adicionar: Eu pensei em vincular uma das páginas úteis da web que encontrei. http://aspneTresources.com/articles/event_handlers_in_global_asax fala sobre como os manipuladores de erro padrão são conectados no Global.asax e me apontaram para o interessante HookupeventHandlersForAppplication e Modules que me deram uma pista sobre como parte disso pode estar funcionando.

Vou adivinhar que o objetivo operacional é fazer algo como, digamos, inicializar a sessão, em vez de precisar fazer algo especificamente no método session_onstart. Presumindo que este é o caso, acho que você pode fazer o seguinte:

1) Lidar com o evento Appication.PostacQuirereQuestState.
2) No manipulador, verifique se a sessão é inicializada-o caminho do homem pobre é definir uma variável na sessão-então o ato adequadamente.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top