我的问题类似但不完全相同:
Why can't my host (softsyshosting.com) support BeginRequest and EndRequest event handlers?(我还阅读了其中引用的mvolo博客)
目标是使用通过system.webServer配置集成的普通HttpModule成功地将HttpApplication.BeginRequest挂接到IHttpModule.Init事件(或模块内部的任何位置),即不会:
覆盖HttpApplication(该模块旨在自包含且可重复使用,例如我有这样的配置):
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules>
<remove name="TheHttpModule" />
<add name="TheHttpModule" type="Company.HttpModules.TheHttpModule" preCondition="managedHandler" />
到目前为止,我尝试将侦听器附加到HttpApplication.BeginRequest的任何策略都会导致以下两种情况之一:症状1是BeginRequest永远不会触发,或者症状2是所有托管请求都抛出以下异常,我无法抓住&amp;从用户代码处理它:
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
在Init中注释掉app.BeginRequest += new EventHandler(this.OnBeginRequest)
会阻止例外。 Init根本不引用Context或Request对象。
我试过了:
有人知道一个好方法吗?在模块中挂钩Application_Start是否有一些间接策略(似乎不太可能)?另一个事件:a)可以从模块的构造函数或Init方法挂钩,以及b)随后是附加BeginRequest事件处理程序的安全位置?
非常感谢
答案 0 :(得分:3)
您的HttpModule的Init方法将被单个Web应用程序多次调用(而global.asax中的Application_Start只会在每个AppDomain上调用一次)。
Init确实是挂钩到BeginRequest的地方。
我也遇到过这个错误,这是因为多次挂钩到BeginRequest事件。我不确定它是否是IIS 7集成模式中的错误...
当您执行app.BeginRequest时,您是使用您的IHttpModule的Init方法的context参数调用context.BeginRequest还是调用HttpContext.Current.BeginRequest + = ...?
答案 1 :(得分:1)
我遇到了上述相同的问题。我发现一个实际的工作是始终删除然后添加处理程序。因此:
public override void Init()
{
base.Init();
lock (_initialisationLockObject)
{
BeginRequest -= Global_BeginRequest;
BeginRequest += Global_BeginRequest;
}
}
我怀疑在一次或多次调用init之后,事件处理程序会被清除。如果你第一次小心地尝试添加事件处理程序,那么init会被调用,以后不会添加一个事件,因此处理程序根本不会被调用。如果您不尝试任何狡猾的事情来限制事件的添加次数,那么您会看到获得多个附件。 通过首先尝试删除然后添加(在锁内停止任何粗糙的竞争条件)似乎做的伎俩。
虽然很可怕,但我们不应该这样做!
希望有所帮助