对静态文件的请求正在命中ASP.NET MVC3中的托管代码

时间:2011-12-05 15:12:12

标签: asp.net-mvc asp.net-mvc-3 iis-7 iis-7.5 ihttpmodule

创建自定义IHttpModules,我意识到对静态文件的请求(例如:.css和.js文件)正在命中托管模块。可能图片有同样的问题。 IIS是否应该绕过文件系统中存在的文件?

例如:

public class MyModule:IHttpModule
{
    public void Dispose(){ }

    public void Init(HttpApplication context)
    {
        context.BeginRequest += (o, e) => Debug.Print("Request: " + HttpContext.Current.Request.RawUrl);
    }
}

我以这种方式宣布:

<modules runAllManagedModulesForAllRequests="true">
  <add name="MyModule" preCondition="managedHandler" type="MVCX.Modules.MyModule, MVCX"/>
</modules>

但是,即使使用前提条件,我也可以看到静态文件如何通过模块:

Request: /MVCX/
Request: /MVCX/Content/Site.css
Request: /MVCX/Scripts/jquery-1.4.4.min.js

我试图忽略静态文件的规则,但它没有什么区别:

routes.IgnoreRoute("{Content}/{*pathInfo}");
routes.IgnoreRoute("{Scripts}/{*pathInfo}");
这是通常的吗?或者我在这里遗漏了什么?据我所知,如果静态文件请求应由IIS回答。如果我的托管模块被命中,意味着CLR ThreadPool线程正在处理该请求,对吗?

问候。

更新:

我已禁用“runAllManagedModulesForAllRequests”:

<modules runAllManagedModulesForAllRequests="false">
      <add name="MyModule" preCondition="managedHandler" type="MVCX.Modules.MyModule, MVCX" />
</modules>

一切似乎都运行得很好,但我发现这篇文章:http://www.britishdeveloper.co.uk/2010/06/dont-use-modules-runallmanagedmodulesfo.html建议删除并读取带有空前置条件的“UrlRoutingModule-4.0”模块。

我的机器,该模块的添加位于根web.config中,并且它已经是一个空的preCondition:

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config>type machine.config | find "UrlRouting"


C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config>type web.config | find "UrlRouting"
            <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />

C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Config>

所以现在我有点困惑,这个参数的状态是什么?我应该使用它还是不应该使用它?为什么它默认为“真实”?

的问候。

5 个答案:

答案 0 :(得分:9)

回答关于IIS应绕过ASP.NET获取静态内容这一事实的第一个问题。

如果在集成模式下配置,IIS 7.5将允许托管模块注册与传统上不由ASP.NET处理的请求相关的事件,如静态文件。

在IIS 7.5经典模式中不会发生这种情况,类似于IIS 6,并且不允许托管模块侦听未由ASP.NET处理的请求中的事件。

因此,基本上如果您使用集成模式runAllManagedModulesForAllRequests="true",则会向您的托管模块通知每个请求的事件。另外,来自documentation on runAllManagedModulesForAllRequests

  

如果所有托管模块都可以处理所有请求,则为真,即使是   请求不适用于托管内容;否则,错误。

     

默认值为false。

该文档未说明此属性如何与preCondition选项进行交互。根据您的经验,它似乎会覆盖preCondition配置,所以如果您是我,我会将其保留在false并使用preCondition选项,即使这意味着更改其他模块的前提条件到一个空字符串,以解决runAllManagedModulesForAllRequests更改为false。


更新: Found some documentation关于使用runAllManagedModulesForAllRequests的影响,如前所述,如果为真,则覆盖preCondition并{ {1}}选项。

  

您还可以使用快捷方式启用所有托管(ASP.NET)模块   运行应用程序中的所有请求,无论如何   “managedHandler”的先决条件。启用所有托管模块   对于所有请求,无需配置每个模块条目以删除   “managedHandler”的先决条件,使用   该部分中的runAllManagedModulesForAllRequests属性:       

     

使用此属性时,“managedHandler”前置条件没有   效果和所有托管模块都针对所有请求运行。

答案 1 :(得分:6)

  

我的机器,该模块的添加位于根web.config中,并且它已经是一个空的前提条件

完美。这意味着该模块将始终运行,这是MVC所需的,因为它使用无扩展的URL。

  

所以现在我有点困惑,这个参数的状态是什么?我应该使用它还是不应该使用它?为什么它默认为“真实”?

因为无扩展URL支持是IIS7 SP1和IIS7.5 SP1中的新增功能。 它可用于IIS7作为您必须请求和安装的补丁。 您可以在这里找到完整的问题答案: http://support.microsoft.com/kb/980368

为什么默认情况下此参数为真?因为VS2010是在IIS7 SP1之前发布的。 也许在VS2010SP1的新MVC项目中它是假的?

答案 2 :(得分:2)

您可以为其编写以下代码。

routes.IgnoreRoute("{*allcss}", new { allaspx = @".*\.css(/.*)?" });
routes.IgnoreRoute("{*alljs}", new { allaspx = @".*\.js(/.*)?" });

请在以下链接中找到更多信息

http://haacked.com/archive/2008/07/14/make-routing-ignore-requests-for-a-file-extension.aspx

答案 3 :(得分:1)

我想,如果你真的想忽略,你不应该使用弯曲的括号:

routes.IgnoreRoute("Content/{*pathInfo}");
routes.IgnoreRoute("Scripts/{*pathInfo}");

答案 4 :(得分:0)

尝试此操作以忽略所有静态文件的列表

routes.IgnoreRoute("{*staticfile}", new { staticfile = @".*\.(js|css|gif|jpg|png)(/.*)?" });