Domanda

Potrei davvero fare con l'aggiornamento delle variabili di sessione di un utente dal mio HTTPModule, ma da quello che posso vedere, non è possibile.

AGGIORNAMENTO: Il mio codice è attualmente in esecuzione all'interno del gestore eventi OnBeginRequest () .

AGGIORNAMENTO: Dopo i consigli ricevuti finora, ho provato ad aggiungere questo alla routine Init () nel mio HTTPModule:

AddHandler context.PreRequestHandlerExecute, AddressOf OnPreRequestHandlerExecute

Ma nella mia routine OnPreRequestHandlerExecute , lo stato della sessione non è ancora disponibile!

Grazie e mi scuso se mi manca qualcosa!

È stato utile?

Soluzione

Trovato questo nei forum ASP.NET :

using System;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
using System.Diagnostics;

// This code demonstrates how to make session state available in HttpModule,
// regradless of requested resource.
// author: Tomasz Jastrzebski

public class MyHttpModule : IHttpModule
{
   public void Init(HttpApplication application)
   {
      application.PostAcquireRequestState += new EventHandler(Application_PostAcquireRequestState);
      application.PostMapRequestHandler += new EventHandler(Application_PostMapRequestHandler);
   }

   void Application_PostMapRequestHandler(object source, EventArgs e)
   {
      HttpApplication app = (HttpApplication)source;

      if (app.Context.Handler is IReadOnlySessionState || app.Context.Handler is IRequiresSessionState) {
         // no need to replace the current handler
         return;
      }

      // swap the current handler
      app.Context.Handler = new MyHttpHandler(app.Context.Handler);
   }

   void Application_PostAcquireRequestState(object source, EventArgs e)
   {
      HttpApplication app = (HttpApplication)source;

      MyHttpHandler resourceHttpHandler = HttpContext.Current.Handler as MyHttpHandler;

      if (resourceHttpHandler != null) {
         // set the original handler back
         HttpContext.Current.Handler = resourceHttpHandler.OriginalHandler;
      }

      // -> at this point session state should be available

      Debug.Assert(app.Session != null, "it did not work :(");
   }

   public void Dispose()
   {

   }

   // a temp handler used to force the SessionStateModule to load session state
   public class MyHttpHandler : IHttpHandler, IRequiresSessionState
   {
      internal readonly IHttpHandler OriginalHandler;

      public MyHttpHandler(IHttpHandler originalHandler)
      {
         OriginalHandler = originalHandler;
      }

      public void ProcessRequest(HttpContext context)
      {
         // do not worry, ProcessRequest() will not be called, but let's be safe
         throw new InvalidOperationException("MyHttpHandler cannot process requests.");
      }

      public bool IsReusable
      {
         // IsReusable must be set to false since class has a member!
         get { return false; }
      }
   }
}

Altri suggerimenti

HttpContext.Current.Session dovrebbe Funziona, supponendo che il tuo Modulo HTTP non stia gestendo eventi della pipeline che si verifica prima dell'inizializzazione dello stato della sessione ...

MODIFICA, dopo chiarimenti nei commenti: durante la gestione di Evento BeginRequest , l'oggetto Session sarà comunque ancora null / Nothing, poiché non è stato ancora inizializzato dal runtime ASP.NET. Per aggirare questo, spostare il codice di gestione su un evento che si verifica dopo PostAcquireRequestState - Mi piace PreRequestHandlerExecute per me stesso, dato che tutto il lavoro di basso livello è praticamente fatto in questa fase, ma prevedi comunque qualsiasi normale elaborazione.

L'accesso al HttpContext.Current.Session in un IHttpModule può essere eseguito nel gestore PreRequestHandlerExecute .

PreRequestHandlerExecute : " Si verifica poco prima che ASP.NET inizi a eseguire un gestore eventi (ad esempio una pagina o un servizio Web XML). " Ciò significa che prima che venga pubblicata una pagina 'aspx' questo evento viene eseguito. Lo "stato della sessione" è disponibile in modo da poterti eliminare.

Esempio:

public class SessionModule : IHttpModule 
    {
        public void Init(HttpApplication context)
        {
            context.BeginRequest += BeginTransaction;
            context.EndRequest += CommitAndCloseSession;
            context.PreRequestHandlerExecute += PreRequestHandlerExecute;
        }



        public void Dispose() { }

        public void PreRequestHandlerExecute(object sender, EventArgs e)
        {
            var context = ((HttpApplication)sender).Context;
            context.Session["some_sesion"] = new SomeObject();
        }
...
}

Se stai scrivendo un normale HttpModule in un'applicazione gestita che desideri applicare alle richieste asp.net tramite pagine o gestori, devi solo assicurarti di utilizzare un evento nel ciclo di vita dopo la creazione della sessione . PreRequestHandlerExecute invece di Begin_Request è di solito dove vado. mdb ha ragione nella sua modifica.

Il frammento di codice più lungo originariamente elencato come risposta alla domanda funziona, ma è complicato e più ampio della domanda iniziale. Gestirà il caso quando il contenuto proviene da qualcosa che non ha un gestore ASP.net disponibile dove è possibile implementare l'interfaccia IRequiresSessionState, innescando così il meccanismo di sessione per renderlo disponibile. (Come un file gif statico su disco). Fondamentalmente sta impostando un gestore fittizio che quindi implementa solo quell'interfaccia per rendere disponibile la sessione.

Se vuoi solo la sessione per il tuo codice, scegli l'evento giusto da gestire nel tuo modulo.

Provalo: nella classe MyHttpModule dichiara:

private HttpApplication contextapp;

Quindi:

public void Init(HttpApplication application)
{
     //Must be after AcquireRequestState - the session exist after RequestState
     application.PostAcquireRequestState += new EventHandler(MyNewEvent);
     this.contextapp=application;
}  

E così, in un altro metodo (l'evento) nella stessa classe:

public void MyNewEvent(object sender, EventArgs e)
{
    //A example...
    if(contextoapp.Context.Session != null)
    {
       this.contextapp.Context.Session.Timeout=30;
       System.Diagnostics.Debug.WriteLine("Timeout changed");
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top