Могу ли я получить доступ к состоянию сеанса из HTTPModule?
Я действительно мог бы сделать с обновлением переменных сеанса пользователя из моего HTTPModule, но из того, что я вижу, это невозможно.
обновление: мой код в настоящее время работает внутри OnBeginRequest ()
обработчик событий.
обновление: следуя советам, полученным до сих пор, я попытался добавить это к Init ()
процедура в моем HTTPModule:
AddHandler context.PreRequestHandlerExecute, AddressOf OnPreRequestHandlerExecute
но в моем OnPreRequestHandlerExecute
рутина, состояние сеанса по-прежнему недоступно!
спасибо, и извиняюсь, если я что-то упустил!
5 ответов:
нашел это на 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.Текущий.Сессия должен просто работать, предполагая, что ваш HTTP-модуль не обрабатывает никаких трубопровод события которые происходят до инициализации состояния сеанса...
редактировать, после уточнения в комментариях: при обработке BeginRequest event, объект сеанса действительно все еще будет null / Nothing, так как он не был инициализирован ASP.NET время выполнения еще есть. Чтобы обойти это, переместите код обработки в событие, которое происходит после PostAcquireRequestState -- мне нравится PreRequestHandlerExecute для этого я сам, так как все низкоуровневые работы в значительной степени выполняются на этом этапе, но вы все равно предвосхищаете любую нормальную обработку.
доступ
HttpContext.Current.Session
наIHttpModule
можно сделатьPreRequestHandlerExecute
обработчик.PreRequestHandlerExecute: "происходит непосредственно перед ASP.NET запускает выполнение обработчика событий (например, страницы или веб-службы XML)."Это означает, что до того, как страница '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(); } ... }
Если вы пишете обычный, базовый HttpModule в управляемом приложении, к которому вы хотите применить asp.net запросы через страницы или обработчики, вы просто должны убедиться, что вы используете событие в жизненном цикле после создания сеанса. PreRequestHandlerExecute вместо Begin_Request, как правило, куда я иду. МБР имеет право на его редактирование.
более длинный фрагмент кода, первоначально указанный как ответ на вопрос, работает, но является сложным и более широким, чем исходный вопрос. Оно будет обрабатывать случай, когда контент поступает из чего-то, что не имеет 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"); } }