Question

Je pourrais vraiment faire avec la mise à jour des variables de session d'un utilisateur à partir de mon HTTPModule, mais d'après ce que je peux voir, ce n'est pas possible.

UPDATE: Mon code est en cours d'exécution dans le gestionnaire d'événements OnBeginRequest () .

UPDATE: À la suite des conseils reçus jusqu'à présent, j'ai essayé de l'ajouter à la routine Init () de mon HTTPModule:

.

AddHandler context.PreRequestHandlerExecute, AddressOf OnPreRequestHandlerExecute

Mais dans ma routine OnPreRequestHandlerExecute , l'état de la session est toujours indisponible!

Merci et excuses s'il me manque quelque chose!

Était-ce utile?

La solution

Vous l'avez trouvé dans les forums 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; }
      }
   }
}

Autres conseils

HttpContext.Current.Session devrait Just Work, en supposant que votre module HTTP ne gère aucun événements de pipeline qui se produire avant l'initialisation de l'état de la session ...

EDIT, après clarification dans les commentaires: lors de la manipulation de BeginRequest , l’objet Session sera toujours null / Nothing, car il n’a pas encore été initialisé par le runtime ASP.NET. Pour résoudre ce problème, déplacez votre code de gestion sur un événement qui se produit après PostAcquireRequestState - J'aime PreRequestHandlerExecute pour moi-même, car tout le travail de bas niveau est quasiment terminé à ce stade, mais vous préemptez toujours tout traitement normal.

L'accès à HttpContext.Current.Session dans un IHttpModule peut être effectué dans le gestionnaire PreRequestHandlerExecute .

PreRequestHandlerExecute : "Apparaît juste avant qu'ASP.NET ne commence à exécuter un gestionnaire d'événements (par exemple, une page ou un service Web XML)." Cela signifie qu'avant l'exécution d'une page 'aspx', cet événement est exécuté. L’état de session est disponible afin que vous puissiez vous assommer.

Exemple:

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();
        }
...
}

Si vous écrivez un HttpModule normal de base dans une application managée que vous souhaitez appliquer aux demandes asp.net via des pages ou des gestionnaires, vous devez simplement vous assurer que vous utilisez un événement dans le cycle de vie après la création de la session. . PreRequestHandlerExecute au lieu de Begin_Request est généralement l'endroit où je vais. mdb a le droit dans son édition.

L'extrait de code plus long indiqué à l'origine comme une réponse à la question fonctionne, mais il est compliqué et plus large que la question initiale. Il gérera le cas où le contenu provient de quelque chose pour lequel aucun gestionnaire ASP.net n'est disponible et où vous pouvez implémenter l'interface IRequiresSessionState, déclenchant ainsi le mécanisme de session pour le rendre disponible. (Comme un fichier gif statique sur le disque). Il s’agit en fait de définir un gestionnaire factice qui implémente ensuite cette interface pour rendre la session disponible.

Si vous souhaitez uniquement utiliser la session pour votre code, il vous suffit de choisir le bon événement à gérer dans votre module.

Essayez-le: dans la classe MyHttpModule declare:

private HttpApplication contextapp;

Ensuite:

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

Et alors, dans une autre méthode (l'événement) de la même 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");
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top