我可以从我的HTTPModule中更新用户的会话变量,但从我看到的情况来看,这是不可能的。

更新:我的代码当前正在 OnBeginRequest()事件处理程序中运行。

更新:根据目前为止收到的建议,我尝试将其添加到HTTPModule中的 Init()例程中:

AddHandler context.PreRequestHandlerExecute,AddressOf OnPreRequestHandlerExecute

但是在我的 OnPreRequestHandlerExecute 例程中,会话状态仍然不可用!

谢谢,如果我错过了什么,请道歉!

有帮助吗?

解决方案

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

其他提示

HttpContext.Current.Session 应该只是工作,假设您的HTTP模块没有处理任何管道事件在会话状态初始化之前发生......

编辑,在评论中澄清:处理 BeginRequest事件,Session对象确实仍然是null / Nothing,因为它还没有被ASP.NET运行时初始化。要解决此问题,请将处理代码移至 PostAcquireRequestState - 我喜欢 PreRequestHandlerExecute 为此我自己,因为所有低级别的工作在这个阶段都已完成,但你仍然会抢先处理任何正常的处理。

IHttpModule 中访问 HttpContext.Current.Session 可以在 PreRequestHandlerExecute 处理程序中完成。

PreRequestHandlerExecute :“在ASP.NET开始执行事件处理程序(例如,页面或XML Web服务)之前发生。”这意味着在提供'aspx'页面之前,会执行此事件。 “会话状态”可用,因此您可以将自己淘汰出局。

示例:

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

如果您在要通过页面或处理程序应用于asp.net请求的托管应用程序中编写正常的基本HttpModule,则只需确保在创建会话后在生命周期中使用事件。 PreRequestHandlerExecute而不是Begin_Request通常是我去的地方。 mdb在他的编辑中是正确的。

最初列为回答问题的较长代码段有效,但比初始问题复杂且广泛。当内容来自没有ASP.net处理程序的内容时,它将处理这种情况,您可以在其中实现IRequiresSessionState接口,从而触发会话机制使其可用。 (就像磁盘上的静态gif文件一样)。它基本上是设置一个虚拟处理程序,然后只是实现该接口以使会话可用。

如果您只想要代码的会话,只需选择要在您的模块中处理的正确事件。

尝试一下:在MyHttpModule类中声明:

private HttpApplication contextapp;

然后:

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

所以,在同一个类的另一个方法(事件)中:

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");
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top