Могу ли я получить доступ к состоянию сеанса из HTTPModule?

Я действительно мог бы обновить переменные сеанса пользователя из моего HTTPModule, но из того, что я вижу, это невозможно.

ОБНОВИТЬ: Мой код в настоящее время выполняется внутри обработчика событий OnBeginRequest ().

ОБНОВИТЬ: Следуя полученному совету, я попытался добавить это в подпрограмму Init () в моем HTTPModule:

AddHandler context.PreRequestHandlerExecute, AddressOf OnPreRequestHandlerExecute

Но в моей программе OnPreRequestHandlerExecute состояние сеанса все еще недоступно!

Спасибо и извиняюсь, если я что-то упускаю!

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
85
0
63 416
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

HttpContext.Current.Session должен просто работать, если ваш HTTP-модуль не обрабатывает конвейерные события, которые возникают до инициализации состояния сеанса ...

ИЗМЕНИТЬ, после пояснения в комментариях: при обработке BeginRequest событие объект Session действительно будет иметь значение null / Nothing, поскольку он еще не был инициализирован средой выполнения ASP.NET. Чтобы обойти это, переместите свой код обработки в событие, которое происходит после PostAcquireRequestState - мне самому нравится PreRequestHandlerExecute, так как вся низкоуровневая работа в значительной степени выполняется на этом этапе, но вы все равно предотвращаете любую нормальную обработку.

К сожалению, это недоступно в HTTPModule - «Ссылка на объект не установлена ​​на экземпляр объекта».

Chris Roberts 09.11.2008 22:39

Я обрабатываю OnBeginRequest?

Chris Roberts 09.11.2008 22:39

Спасибо за обновление. Если я обрабатываю его в событии уровня приложения, почему бы мне просто не выполнять всю свою обработку на уровне приложения вместо использования HTTPModule?

Chris Roberts 09.11.2008 22:47

PostAcquireRequeststate не является «событием уровня приложения»: например, если HTTP-запрос обрабатывается обработчиком веб-службы, вы все равно увидите его в своем HTTP-модуле, но не в Global.asax ...

mdb 09.11.2008 22:50

Похоже, это не работает для меня надежно. Следующий код часто вызывает исключение «Состояние сеанса недоступно в этом контексте». Фактически, это довольно эффектно вызывает сбой отладчика VS. context.PreRequestHandlerExecute + = (отправитель, аргументы) => Console.Write (((HttpApplication) отправитель) .Session ["тест"];

cbp 24.05.2011 11:19

Я пробую это, и, похоже, все работает нормально, кроме запросов GET - теперь они не проходят мимо события ResolveRequestCache. Раньше у меня было все в AuthenticateRequest (до ResolveRequestCache), но теперь я переместил свой код в PreRequestHandlerExecute, чтобы я мог использовать состояние сеанса. Сначала оказалось, что мой HTTP-модуль даже не видит запросы GET, но, подписавшись на каждое событие в жизненном цикле HTTP-модуля и регистрируя каждое из них, я вижу, что мои запросы GET проходят, но останавливаются после события ResolveRequestCache. Какие-нибудь мысли?

lhan 22.01.2013 01:20

Я также должен отметить, что Fiddler показывает 404-Not found для моих запросов GET. Есть ли параметр в IIS, который мне нужно изменить, чтобы это решение работало с GET?

lhan 22.01.2013 01:21
Ответ принят как подходящий

Нашел это на Форумы 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,
// regardless 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; }
      }
   }
}

MS должна это исправить! ... если я помечу модуль как реализующий IRequiresSessionState, мне не придется прыгать через обруч, чтобы получить его ... (действительно сексуальный код)

BigBlondeViking 29.07.2009 00:26

Хороший код. Я думал, мне это понадобится, но оказалось, что нет. Этот код завершает загрузку сеанса для каждого изображения и других ресурсов, не относящихся к странице, которые проходят через сервер. В моем случае я просто проверяю, является ли сеанс нулевым в событии PostAcquireRequestState, и возвращаю, если это так.

Abtin Forouzandeh 25.02.2010 02:27

Этот код полезен, если запрошенный ресурс не обрабатывает состояние сеанса. Для стандартных страниц .aspx просто добавьте код доступа к сеансу в обработчике событий PostAcquireRequestState. Состояние сеанса не будет доступно ни для одного обработчика событий BeginRequest, поскольку состояние сеанса еще не получено.

JCallico 18.06.2010 23:32

Фантастический. Спасибо, amigo, этот код действительно помог использовать HttpContext.Current.User в HttpModule

user29964 21.06.2010 17:45

Для тех, кто хочет использовать этот «хак», единственный способ получить эту работу - заставить временный обработчик использовать IReadOnlySessionState вместо IRequiresSessionState.

nokturnal 17.01.2013 00:05

В моем случае это не работает. Я получил сообщение «Состояние сеанса недоступно в этом контексте». когда есть запрос, пытающийся получить доступ к статическому файлу. Любая помощь ?

maxisam 22.07.2013 22:05
OriginalHandler.ProcessRequest(context); в ProcessRequest, если ваш код на самом деле вызывает ProcessRequest(<C>)
TheGeekZn 08.08.2014 13:16

Чтобы это работало со статическими файлами, я, кроме того, повторно зарегистрировал модуль сеанса (в web.config), удалив preCondition = "managedHandler" (<remove name = "Session" /> <add name = " Session "type = " System.Web.SessionState.SessionStateModule "/>)

nlips 04.12.2014 15:45

Это сработало для защиты папки с файлами PDF с использованием моего существующего кода входа / сеанса. Я нашел аналогичную реализацию, которая разбивает ее на 3 раздела, выполняя проверку сеанса в PreRequestHandlerExecute. Я нашел это более ясным для понимания. martinwilley.com/net/code/AuthorizeModule.html. Я выбрал IReadOnlySessionState как nokturnal, чтобы не бездельничать, а также нуждался в изменении web.config с @nlips

goodeye 13.12.2014 21:10

использование SetSessionStateBehavior намного проще, чем реализация обходного пути в этом ответе.

zzzzBov 05.03.2015 01:35

Если вы пишете обычный, базовый HttpModule в управляемом приложении, которое хотите применить к запросам asp.net через страницы или обработчики, вам просто нужно убедиться, что вы используете событие в жизненном цикле после создания сеанса. PreRequestHandlerExecute вместо Begin_Request обычно то место, куда я иду. mdb имеет это право в его редактировании.

Более длинный фрагмент кода, изначально указанный как ответ на вопрос, работает, но он сложнее и шире исходного вопроса. Он будет обрабатывать случай, когда контент поступает из чего-то, что не имеет доступного обработчика ASP.net, где вы можете реализовать интерфейс IRequiresSessionState, тем самым запуская механизм сеанса, чтобы сделать его доступным. (Как статический файл в формате gif на диске). По сути, он устанавливает фиктивный обработчик, который затем просто реализует этот интерфейс, чтобы сделать сеанс доступным.

Если вам просто нужен сеанс для вашего кода, просто выберите правильное событие для обработки в вашем модуле.

Доступ к 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();
        }
...
}

Я попробовал это, и вы действительно получили сеанс. Но похоже, что RequestHeader там не полностью, особенно HeaderContentType

Matthias Müller 19.05.2014 13:50

Попробуйте: в классе 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");
    }
}

Другие вопросы по теме