我可以从HTTPModule访问会话状态吗?
我真的可以从我的HTTPModule更新用户的会话variables,但从我可以看到,这是不可能的。
更新:我的代码当前正在OnBeginRequest ()
事件处理程序中运行。
更新:到目前为止收到的build议,我试图将其添加到我的HTTPModule中的Init ()
例程:
AddHandler context.PreRequestHandlerExecute, AddressOf OnPreRequestHandlerExecute
但在我的OnPreRequestHandlerExecute
例程中,会话状态仍然不可用!
谢谢,如果我失去了一些东西,我很抱歉!
在ASP.NET论坛上find了这个:
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模块不处理会话状态被初始化之前发生的任何pipe道事件 …
编辑,澄清后的意见:在处理BeginRequest事件时 ,会话对象将确实仍然为空/无,因为它还没有被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(); } ... }
如果您要在托pipe应用程序中编写一个正常的基本HttpModule,并希望通过页面或处理程序将其应用于asp.net请求,则必须确保在创build会话后生命周期中使用了一个事件。 PreRequestHandlerExecute而不是Begin_Request通常是我去的地方。 mdb在编辑中是正确的。
最初被列为回答问题的较长的代码片段起作用,但比最初的问题复杂和广泛。 它将处理内容来自没有可用的ASP.net处理程序的情况,您可以在其中实现IRequiresSessionState接口,从而触发会话机制使其可用。 (就像磁盘上的静态gif文件)。 这基本上是设置一个虚拟处理程序,然后只是实现该接口,使会议可用。
如果你只是想要你的代码的会话,只需select正确的事件来处理你的模块。
尝试一下:在类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; }
所以,在同一个class级的另一种方法(事件)中:
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"); } }