C# HttpModule.Init-在IIS7集成模式下安全添加HttpApplication.BeginRequest处理程序

C# HttpModule.Init-在IIS7集成模式下安全添加HttpApplication.BeginRequest处理程序,c#,iis-7,httpmodule,integrated-pipeline-mode,C#,Iis 7,Httpmodule,Integrated Pipeline Mode,我的问题类似但不完全相同: (我还阅读了其中引用的mvolo博客) 目标是使用通过system.webServer配置集成的普通HttpModule成功地将HttpApplication.BeginRequest挂接到IHttpModule.Init事件中(或模块内部的任何位置),即不: 入侵Global.asax或 覆盖HttpApplication(该模块旨在自包含和可重用,因此,例如,我有一个这样的配置): 在Init中注释掉app.BeginRequest+=neweventhandle

我的问题类似但不完全相同:

(我还阅读了其中引用的mvolo博客)

目标是使用通过system.webServer配置集成的普通HttpModule成功地将HttpApplication.BeginRequest挂接到IHttpModule.Init事件中(或模块内部的任何位置),即不:

  • 入侵Global.asax或
  • 覆盖HttpApplication(该模块旨在自包含和可重用,因此,例如,我有一个这样的配置):

    在Init中注释掉app.BeginRequest+=neweventhandler(this.OnBeginRequest)当然会停止异常。Init根本不引用上下文或请求对象

    我试过:

    • 删除了项目中任何地方对HttpContext.Current的所有引用(仍然是症状1)
    • 已测试从OnBeginRequest方法体中删除所有代码,以确保问题不是该方法内部的(=异常)
    • 嗅探堆栈跟踪并仅调用app.BeginRequest+=。。。如果堆栈不是通过InitializeApplication(=BeginRequest not Firening)启动的
    • 仅在第二次通过初始化时调用app.BeginRequest+=(=BeginRequest未触发)
    有人知道一个好方法吗?是否有一些间接策略用于在模块内挂接应用程序启动(似乎不太可能)?a)可以从模块的构造函数或Init方法钩住的另一个事件,以及b)随后连接BeginRequest事件处理程序的安全位置


    非常感谢

    您的HttpModule的Init方法将被单个web应用程序调用多次(而在您的global.asax中启动的应用程序只会被每个AppDomain调用一次)

    Init确实是连接BeginRequest的地方

    我也遇到过这个错误,它是由多次挂接BeginRequest事件引起的。我不确定它是否是IIS 7集成模式中的错误


    执行app.BeginRequest时,是使用IHttpModule的Init方法的context参数调用context.BeginRequest,还是调用HttpContext.Current.BeginRequest+=…?

    我遇到了上述相同的问题。我发现一个实际的解决方法是总是删除然后添加处理程序。因此:

        public override void Init()
        {
            base.Init();
    
            lock (_initialisationLockObject)
            {
                BeginRequest -= Global_BeginRequest;
                BeginRequest += Global_BeginRequest;
            }
        }
    
    我怀疑在对init进行一次或多次调用后,事件处理程序正在被清除。如果您只在第一次小心地尝试添加事件处理程序,那么稍后调用init时不会添加事件,因此根本不会调用该处理程序。如果您不尝试任何巧妙的方法来限制事件的添加次数,那么您将看到获得多个附件。 首先尝试删除然后添加(在锁内以阻止任何恶劣的竞争条件)似乎可以做到这一点

    这是可怕的,但我们不应该这样做


    希望这有助于

    void IHttpModule.Init(HttpApplication app)
    中,我调用
    app.BeginRequest+=neweventhandler(this.OnApplication\u BeginRequest)
    。然后我使用一个类级静态bool,_inited,以防止多次添加处理程序。这就是为什么这种情况会让我陷入这样的困境的部分原因。这里也有同样的问题。我还在IIS网站上发布了一条帖子,希望微软的人能给出答案:有解决方案吗?我可以将httpModule添加到任何ASP.NET应用程序中。但是,我在尝试将IHTTP模块添加到SharePoint 2013网站(.NET 4.0)时遇到了完全相同的错误。当我附加到BeginRequest事件时,问题就出现了。@PaulSmith,我不确定我是否理解,您是否试图在基于请求的HttpModule内附加应用程序范围的事件?如果您试图附加应用程序范围的事件,则在Global.asax.cs中有一个应用程序启动。IHttpModule.Init将在每个保持活动的请求中调用一次在我的情况下,我只需要执行以下操作:System.Web.HttpContext.Current.ApplicationInstance.BeginRequest+=ApplicationInstance\u BeginRequest;但在+=-=workedWorkAround中,它会引发空指针异常。您不应该从httpModule附加全局事件,请使用global.asax.cs中的Application_xxx或Session_xxx方法
    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
    
        public override void Init()
        {
            base.Init();
    
            lock (_initialisationLockObject)
            {
                BeginRequest -= Global_BeginRequest;
                BeginRequest += Global_BeginRequest;
            }
        }