HttpModule.Init - безопасно добавлять обработчик HttpApplication.BeginRequest в интегрированном режиме IIS7 - PullRequest
11 голосов
/ 15 сентября 2010

Мой вопрос похож, но не идентичен:

Почему мой хост (softsyshosting.com) не поддерживает обработчики событий BeginRequest и EndRequest? (я также читал блог mvolo, на который есть ссылки)

Цель состоит в том, чтобы успешно перехватить HttpApplication.BeginRequest в событии IHttpModule.Init (или в любом месте внутри модуля), используя обычный модуль HttpModule, интегрированный через конфигурацию system.webServer, то есть тот, который не:

  1. вторжение в Global.asax или
  2. переопределяет HttpApplication (модуль предназначен для автономного и многократного использования, поэтому, например, у меня есть такая конфигурация):

    <system.webServer>
    <validation validateIntegratedModeConfiguration="false"/>
    <modules>
      <remove name="TheHttpModule" />
      <add name="TheHttpModule" type="Company.HttpModules.TheHttpModule" preCondition="managedHandler" /> 
    

Пока что любая стратегия, которую я пытался подключить к HttpApplication.Begin слушателя, приводит к одной из двух причин: симптом 1 состоит в том, что BeginRequest никогда не срабатывает, или симптом 2 заключается в том, что следующее исключение возникает во всех управляемых запросах, и я не могу поймать и обработать его из кода пользователя:

Stack Trace:
[NullReferenceException: Object reference not set to an instance of an object.]
System.Web.PipelineModuleStepContainer.GetEventCount(RequestNotification notification, Boolean isPostEvent) +30
System.Web.PipelineStepManager.ResumeSteps(Exception error) +1112
System.Web.HttpApplication.BeginProcessRequestNotification(HttpContext context, AsyncCallback cb) +113
System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +616

Комментирование app.BeginRequest += new EventHandler(this.OnBeginRequest) в Init останавливает исключение, конечно. Init вообще не ссылается на объекты Context или Request.

Я пробовал:

  • Удалено все ссылки на HttpContext.Current в любом месте проекта (все еще симптом 1)
  • Протестировано удаление всего кода из тела моего метода OnBeginRequest, чтобы убедиться, что проблема не является внутренней по отношению к методу (= исключение)
  • Обнаружение трассировки стека и вызов только app.BeginRequest + = ... когда стек не запущен InitializeApplication (= BeginRequest не запускается)
  • Только вызывая app.BeginRequest + = при втором проходе через Init (= BeginRequest не запускается)

Кто-нибудь знает хороший подход? Есть ли какая-то косвенная стратегия для перехвата Application_Start внутри модуля (кажется маловероятным)? Другое событие, которое а) можно подключить к конструктору модуля или методу Init, и б) которое впоследствии является безопасным местом для подключения обработчиков событий BeginRequest?

Большое спасибо

Ответы [ 2 ]

3 голосов
/ 15 сентября 2010

Метод Init вашего HttpModule будет вызываться несколько раз одним веб-приложением (тогда как Application_Start в вашем global.asax будет вызываться только один раз для каждого AppDomain).

Инициатива действительно является местом для подключения к BeginRequest.

Я также столкнулся с этой ошибкой, и она была вызвана подключением к событию BeginRequest более одного раза.Я не уверен, является ли это ошибкой в ​​интегрированном режиме IIS 7 или нет ...

Когда вы делаете app.BeginRequest, вы вызываете context.BeginRequest, используя параметр context для метода Init вашего IHttpModule, или вывызов HttpContext.Current.BeginRequest + = ...?

1 голос
/ 06 февраля 2015

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

    public override void Init()
    {
        base.Init();

        lock (_initialisationLockObject)
        {
            BeginRequest -= Global_BeginRequest;
            BeginRequest += Global_BeginRequest;
        }
    }

Я подозреваю, что обработчики событий очищаются после одного или нескольких вызовов init. Если вы тщательно только попытаетесь добавить обработчик события в первый раз, в более поздние времена вызывается init, но не добавляется событие, и, следовательно, обработчик вообще не вызывается. Если вы не попробуете ничего хитрого, чтобы ограничить количество добавлений события, вы видели, как получить несколько вложений. Сначала попытка удалить, а затем добавить (внутри блокировки, чтобы остановить любые грубые условия гонки), кажется, добивается цели.

Хотя это ужасно, и мы не должны были этого делать!

Надеюсь, что поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...