我可以从HTTPModule访问会话状态吗?

Chr*_*rts 85 asp.net session-state httpmodule

我真的可以从我的HTTPModule中更新用户的会话变量,但从我所看到的,它是不可能的.

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

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

AddHandler context.PreRequestHandlerExecute, AddressOf OnPreRequestHandlerExecute

但在我的OnPreRequestHandlerExecute日常工作中,会话状态仍然不可用!

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

Jim*_*rte 82

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; }
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

  • MS应该解决这个问题!...如果我将一个模块标记为实现IRequiresSessionState,我不应该跳过一个环来获得它......(性感的代码确实) (8认同)
  • 如果请求的资源不处理会话状态,则此代码很有用.对于标准的.aspx页面,只需在PostAcquireRequestState事件处理程序中添加访问会话的代码.会话状态将不会在任何BeginRequest事件处理程序上可用,因为尚未获取会话状态. (7认同)
  • 好的代码.我以为我需要这个,但事实证明并非如此.此代码最终为每个映像和通过服务器的其他非页面资源加载会话.在我的例子中,我只是检查PostAcquireRequestState事件中的session是否为null,如果是则返回. (6认同)
  • 它在我的情况下不起作用.我得到了"会话状态在这种情况下不可用".当有请求尝试访问静态文件时.有帮助吗? (3认同)
  • 为了对静态文件起作用,我还通过删除preCondition ="managedHandler"(<remove name ="Session"/> <add name =")重新注册会话模块(在web.config中).会话"type ="System.Web.SessionState.SessionStateModule"/>) (3认同)

mdb*_*mdb 39

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

EDIT,在注释中澄清:处理BeginRequest事件时,Session对象确实仍然是null/Nothing,因为它还没有被ASP.NET运行时初始化.要解决这个问题,请将处理代码移动到PostAcquireRequestState之后发生的事件- 我自己也喜欢PreRequestHandlerExecute,因为所有低级工作在此阶段都已完成,但您仍然抢先处理任何正常处理.


Ber*_*syn 15

访问HttpContext.Current.Sessionin中IHttpModule可以在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();
        }
...
}
Run Code Online (Sandbox Code Playgroud)


Rob*_*Rob 12

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

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

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