C# BeginRequest被调用两次
我已经创建了一个C# BeginRequest被调用两次,c#,asp.net,.net,iis,C#,Asp.net,.net,Iis,我已经创建了一个HttpModule: using System; using System.Web; public class TestModule : IHttpModule { public TestModule() { } public String ModuleName { get { return "TestModule"; } } public void Dispose() { } public void Init(HttpApplica
HttpModule
:
using System;
using System.Web;
public class TestModule : IHttpModule
{
public TestModule() { }
public String ModuleName { get { return "TestModule"; } }
public void Dispose() { }
public void Init(HttpApplication app)
{
app.BeginRequest += (new EventHandler(this.DoBeginRequest));
}
private void DoBeginRequest(Object source, EventArgs e)
{
HttpApplication application = (HttpApplication)source;
HttpContext context = application.Context;
context.Response.Write("<pre>Request URL: " + context.Request.FilePath + "</pre>");
context.Response.Flush();
System.Diagnostics.Debug.WriteLine(context.Request.ToString());
}
}
Headers == Accept=*%2f*&Host=localhost%3a2017&User-Agent=curl%2f7.35.0
Headers == Content-Length=0&Accept=*%2f*&Host=localhost%3a2017&User-Agent=curl%2f7.35.0
具体来说,内容长度
头在第二次调用时设置。这在发出的请求curl
中不存在:
<system.webServer>
<handlers>
<remove name="ExtensionlessUrl-Integrated-4.0" />
</handlers>
<modules>
<add name="TestModule" type="TestModule"/>
</modules>
</system.webServer>
这是IIS试图提供帮助吗?处理完整个请求后,它知道主体的长度(0),并使用该集合再次调用它?使用LogRequest事件侦听器而不是BeginRequest应该可以满足您的需要: 是的,我在非常干净的ASP.NET Web应用程序上看到了您的行为。 它与favicon.ico附加请求无关。
它可能与IIS在应用程序池中创建的多个应用程序实例有关。以及具有对同一事件的多个订阅的模块的多个实例。它就在这里的某个地方……但是我现在无法在我的代码中证明这些理论。好吧,在经历了很多挫折之后,我发现特定的URL没有受到这种行为的影响。带有“扩展名”的URL不会这样做: 通过进一步的在线挖掘,我找到了一个名为
ExtensionlessUrl-Integrated-4.0
的处理程序的引用,该处理程序由主配置文件applicationhost.config
加载。我真的不知道这是在做什么,也不知道它为什么会导致请求重复,但在我自己的web.config
中明确删除它解决了问题:
我必须承认,我有点担心我以后可能会遇到其他类似的陷阱-
applicationhost.config
加载了许多其他处理程序和模块,其中任何一个都可能在我的模块能够处理它之前弄乱了这样的东西。但这是另一天的问题…问题可能隐藏在很多地方。。。我建议在响应值附加字符串的地方设置一个断点,并查看第二次触发的时间。检查调用堆栈以查看是谁发起了第二次调用。是否有方法将IISExpress置于某种调试模式?我在调用堆栈中看到的只是DoBeginRequest
之前的[External code]
非常有趣的IIS行为……您可能会发现本文很有用,但它的解决方案在我们的案例中不起作用:使用LogRequest
似乎行为正确,但使用它来做实际工作感觉不“正确”(在本例中,我将使用它通过一些IPC机制有效地代理另一个进程)。我也没有信心我对它理解得足够透彻,能够依靠LogRequest
工作!进一步调查后,LogRequest
也被调用了两次,但是只有一个响应流
返回到客户端。IIS总是这么难吗?我感觉就是这样一个简单的“Hello World”应用程序,但有些地方仍然很不对劲,我肯定错过了一些明显的东西。
Headers == Accept=*%2f*&Host=localhost%3a2017&User-Agent=curl%2f7.35.0
Headers == Content-Length=0&Accept=*%2f*&Host=localhost%3a2017&User-Agent=curl%2f7.35.0
> GET /example HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:2017
> Accept: */*
public void Init(HttpApplication app)
{
app.LogRequest += DoBeginRequest; // TODO: Rename your function
}
curl http://localhost:2017/test
> BeginRequest
> BeginRequest
curl http://localhost:2017/test.abc
> BeginRequest
curl http://localhost:2017/.a
> BeginRequest
<system.webServer>
<handlers>
<remove name="ExtensionlessUrl-Integrated-4.0" />
</handlers>
<modules>
<add name="TestModule" type="TestModule"/>
</modules>
</system.webServer>