SharePoint 2013, пользовательский IHttpModule NullReferenceException

Обновление: проблема решена. Читать дальше.

Любая идея, почему, по-видимому, больше невозможно добавить пользовательские модули IHttp?

Мой вопрос связан с: HttpModule.Init - безопасно добавьте обработчик HttpApplication.BeginRequest в интегрированном режиме IIS7. Однако этот вопрос довольно старый, без ответа и не имеет контекста SharePoint. Я МОГУ добавить свой HttpModule на любую стандартную страницу веб-форм ASP.NET.

SharePoint размещается в IIS 8. AppPool работает в интегрированном режиме. Уровень структуры 4.0+.

namespace My.Namespace
{
    using System;
    using System.Web;

    public class CustomHttpModule : IHttpModule
    {
        private static readonly object mutex = new object();
        private static bool _isInitialized;

        public void Init(HttpApplication context)
        {
            if (!_isInitialized)
            {
                lock (mutex)
                {
                    if (_isInitialized) return;

                    context.BeginRequest += BeginRequest;
                    _isInitialized = true;
                }
            }
        }

        private void BeginRequest(object sender, EventArgs e)
        {   
        }

        public void Dispose()
        {
        }
    }
}

Результат:

[NullReferenceException: ссылка на объект не установлена ​​для экземпляра объекта.] System.Web.PipelineModuleStepContainer.GetEventCount(уведомление RequestNotification, логическое значение isPostEvent) +30
System.Web.PipelineStepManager.ResumeSteps (ошибка исключения) +1098
System.Web.HttpApplication.BeginProcessRequestNotification (контекст HttpContext, AsyncCallback cb) +135
System.Web.HttpRuntime.ProcessRequestNotificationPrivate (IIS7WorkerRequest wr, контекст HttpContext) +604

Файл web.config выглядит следующим образом:

<system.webServer>
<!-- further elements omitted -->
<modules runAllManagedModulesForAllRequests="true">
  <remove name="AnonymousIdentification" />
  <remove name="FileAuthorization" />
  <remove name="Profile" />
  <remove name="WebDAVModule" />
  <remove name="Session" />
  <add name="SPNativeRequestModule" preCondition="integratedMode" />
  <add name="SPRequestModule" preCondition="integratedMode" type="Microsoft.SharePoint.ApplicationRuntime.SPRequestModule, Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
  <add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  <add name="SharePoint14Module" preCondition="integratedMode" />
  <add name="StateServiceModule" type="Microsoft.Office.Server.Administration.StateModule, Microsoft.Office.Server, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
  <add name="PublishingHttpModule" type="Microsoft.SharePoint.Publishing.PublishingHttpModule, Microsoft.SharePoint.Publishing, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
  <add name="DesignHttpModule" preCondition="integratedMode" type="Microsoft.SharePoint.Publishing.Design.DesignHttpModule, Microsoft.SharePoint.Publishing, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
  <add name="FederatedAuthentication" type="Microsoft.SharePoint.IdentityModel.SPFederationAuthenticationModule, Microsoft.SharePoint.IdentityModel, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
  <add name="SessionAuthentication" type="Microsoft.SharePoint.IdentityModel.SPSessionAuthenticationModule, Microsoft.SharePoint.IdentityModel, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
  <add name="SPWindowsClaimsAuthentication" type="Microsoft.SharePoint.IdentityModel.SPWindowsClaimsAuthenticationHttpModule, Microsoft.SharePoint.IdentityModel, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
  <add name="SPApplicationAuthentication" type="Microsoft.SharePoint.IdentityModel.SPApplicationAuthenticationModule, Microsoft.SharePoint.IdentityModel, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />
  <add name="Session" type="System.Web.SessionState.SessionStateModule" />
  <add name="CustomModule" type="My.Namespace.CustomHttpModule, My.Namespace, Version=1.0.0.0, Culture=neutral, PublicKeyToken=066b2229567b6747" />
</modules>
<!-- further elements omitted -->
</system.webServer>

Как только я больше не присоединяюсь к событию BeginRequest, страница снова работает. Но, очевидно, мой http-модуль оказывается бесполезным.

Изменить 2013.09.19: Init() вызывается дважды при запуске приложения. Если я присоединяю свое событие только ко второму вызову, приложение работает, но событие не срабатывает.

Edit 2013.09.20: проблема предположительно решена. Тот факт, что мой метод Init() запускается дважды (и никакой метод Dispose() не вызывается) привел меня к предположению, что на самом деле могут существовать два сосуществующих экземпляра моего IHttpModule. И хотя мое предыдущее наблюдение показало, что ко второму экземпляру может быть прикреплено событие (не запускающее, но и не оказывающее негативного влияния на приложение) - это, очевидно, неверно, наоборот (что имеет место с моей статической _isInitialized "блокировкой"),

** Таким образом, оба экземпляра IHttpModule должны иметь одинаковую "конфигурацию" (прикрепленные обработчики событий). Совершенно нормально, если запущено несколько экземпляров HttpApplication. Это то, что ASP.NET (или IIS) делает внутренне для целей оптимизации. Это главное, что нужно запомнить:)

1 ответ

Задача решена. Отредактированный вопрос. См. Правка 2013.09.20.

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