BeginRequest被调用两次

时间:2017-02-06 16:06:11

标签: 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(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());
    }
}

这样加载:

<system.webServer>
  <modules>
    <add name="TestModule" type="TestModule"/>
  </modules>
</system.webServer>

当我从网络浏览器或curl调用此内容时,我在“输出”选项卡中显示两条日志行,我看到以下响应:

<pre>Request URL: /example</pre><pre>Request URL: /example</pre>

表示每次都是相同的Context。 为什么会发生这种情况? Request对象中有很多字段,但我无法在两次调用中发现它们之间存在任何差异。是否有一些属性,我应该检查,给出一个&#34;阶段&#34;我应该只回应其中一个?

我在网站上发现了一些相关的问题,但是大多数人似乎都倾向于使用网络浏览器寻找其他资源,例如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

具体来说,第二次调用时会设置Content-Length标头。这个请求curl中没有出现:

> GET /example HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:2017
> Accept: */*

这个IIS是否有用?在处理完整个请求后,它知道正文是多长时间(0)并再次使用该集合调用它?

2 个答案:

答案 0 :(得分:2)

好的,经过多次挫折后,我发现的特定网址遭受此行为。带有&#34;扩展名的网址&#34;不要这样做:

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

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

curl http://localhost:2017/.a
 > BeginRequest

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

   <system.webServer>
      <handlers>
        <remove name="ExtensionlessUrl-Integrated-4.0" />
      </handlers>
      <modules>
        <add name="TestModule" type="TestModule"/>
      </modules>
    </system.webServer>

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

答案 1 :(得分:0)

使用LogRequest事件监听器而不是BeginRequest应该适用于您的目的:

public void Init(HttpApplication app)
{
    app.LogRequest += DoBeginRequest; // TODO: Rename your function
}

是的,我在非常干净的ASP.NET Web应用程序上看到了您的行为。 它与favicon.ico附加请求无关。 它可能与IIS可能在应用程序池中创建的多个应用程序实例有关。并且您的模块的多个实例具有对同一事件的多个订阅。它在某处...但我现在无法在我的代码中证明这些理论。