Pregunta

Realmente podría hacer con la actualización de las variables de sesión de un usuario desde mi HTTPModule, pero por lo que puedo ver, no es posible.

ACTUALIZACIÓN: Mi código se está ejecutando actualmente dentro del controlador de eventos OnBeginRequest () .

ACTUALIZACIÓN: Siguiendo los consejos recibidos hasta ahora, intenté agregar esto a la rutina Init () en mi HTTPModule:

AddHandler context.PreRequestHandlerExecute, AddressOf OnPreRequestHandlerExecute

Pero en mi rutina OnPreRequestHandlerExecute , ¡el estado de la sesión aún no está disponible!

¡Gracias y disculpas si me falta algo!

¿Fue útil?

Solución

Encontré esto en los foros 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; }
      }
   }
}

Otros consejos

HttpContext.Current.Session debería Simplemente trabaje, suponiendo que su módulo HTTP no esté manejando ningún eventos de canalización que ocurrir antes de que se inicialice el estado de la sesión ...

EDITAR, después de la aclaración en los comentarios: al manejar el Evento BeginRequest , el objeto Session seguirá siendo nulo / Nada, ya que aún no ha sido inicializado por el tiempo de ejecución ASP.NET. Para evitar esto, mueva su código de manejo a un evento que ocurra después de PostAcquireRequestState - Me gusta PreRequestHandlerExecute para mí mismo, ya que todo el trabajo de bajo nivel se realiza prácticamente en esta etapa, pero aún así se adelanta a cualquier procesamiento normal.

El acceso al HttpContext.Current.Session en un IHttpModule se puede hacer en el controlador PreRequestHandlerExecute .

PreRequestHandlerExecute : " Ocurre justo antes de que ASP.NET comience a ejecutar un controlador de eventos (por ejemplo, una página o un servicio web XML). " Esto significa que antes de que se publique una página 'aspx', este evento se ejecuta. El 'estado de sesión' está disponible para que pueda noquearse.

Ejemplo:

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 está escribiendo un HttpModule básico normal en una aplicación administrada que desea aplicar a las solicitudes asp.net a través de páginas o controladores, solo tiene que asegurarse de estar usando un evento en el ciclo de vida después de la creación de la sesión . PreRequestHandlerExecute en lugar de Begin_Request es generalmente a donde voy. mdb lo tiene bien en su edición.

El fragmento de código más largo originalmente listado como respuesta a la pregunta funciona, pero es complicado y más amplio que la pregunta inicial. Manejará el caso cuando el contenido provenga de algo que no tenga un controlador ASP.net disponible donde pueda implementar la interfaz IRequiresSessionState, activando así el mecanismo de sesión para que esté disponible. (Como un archivo gif estático en el disco). Básicamente se trata de configurar un controlador ficticio que luego solo implementa esa interfaz para que la sesión esté disponible.

Si solo desea la sesión para su código, simplemente elija el evento correcto para manejar en su módulo.

Pruébelo: en la clase MyHttpModule declare:

private HttpApplication contextapp;

Entonces:

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

Y así, en otro método (el evento) en la misma clase:

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");
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top