BeginRequest 被调用两次

Sti*_*tik 4 .net c# asp.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(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());
    }
}
Run Code Online (Sandbox Code Playgroud)

其加载方式如下:

<system.webServer>
  <modules>
    <add name="TestModule" type="TestModule"/>
  </modules>
</system.webServer>
Run Code Online (Sandbox Code Playgroud)

当我从 Web 浏览器或从 调用此函数时curl,我在“输出”选项卡中收到两条日志行,并且看到以下响应:

<pre>Request URL: /example</pre><pre>Request URL: /example</pre>
Run Code Online (Sandbox Code Playgroud)

这表明每次都是相同的 Context。 为什么会发生这种情况? 对象中有很多字段Request,但我无法在两次调用中发现它们之间的任何区别。是否有一些我应该检查的属性提供了一个我应该只响应其中一个的“阶段”?

我在网站上发现了一些相关的问题,但大多数问题似乎倾向于网络浏览器寻找其他资源,例如favicon.ico,但这里的情况并非如此。

MSDN似乎对 的细节有点了解BeginRequest,所以到目前为止我还没有找到很多帮助。

我可能遗漏了一些明显的东西,这是我第一次接触 .NET/IIS 等,我通常是一名 Java 开发人员。

更新

我已经转储了所有公共属性Request,这是两者之间的区别:

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
Run Code Online (Sandbox Code Playgroud)

具体来说,Content-Length标头是在第二次调用时设置的。这在提出的请求中不存在curl

> GET /example HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:2017
> Accept: */*
Run Code Online (Sandbox Code Playgroud)

这个 IIS 是否想提供帮助?在处理整个请求后,它知道主体有多长(0)并用该集合再次调用它?

Sti*_*tik 5

好吧,经过多次挫折后,我发现特定的 URL 并没有受到这种行为的影响。带有“扩展名”的 URL 不会这样做:

curl http://localhost:2017/test
 > BeginRequest
 > BeginRequest 

curl http://localhost:2017/test.abc
 > BeginRequest

curl http://localhost:2017/.a
 > BeginRequest
Run Code Online (Sandbox Code Playgroud)

通过更多的在线挖掘,我发现了对名为 Handler 的引用ExtensionlessUrl-Integrated-4.0,该处理程序由主配置文件加载applicationhost.config。我真的不知道这是在做什么,也不知道为什么它会导致请求重复,但在我自己的中显式删除它web.config已经解决了问题:

   <system.webServer>
      <handlers>
        <remove name="ExtensionlessUrl-Integrated-4.0" />
      </handlers>
      <modules>
        <add name="TestModule" type="TestModule"/>
      </modules>
    </system.webServer>
Run Code Online (Sandbox Code Playgroud)

我必须承认,我有点担心以后可能会遇到其他类似的陷阱 -applicationhost.config加载许多其他处理程序和模块,其中任何一个都可能在我的模块能够获取它之前弄乱这样的东西。但这是另一天的问题......