【问题标题】:Can't stop firing ASP.NET Module for static content无法停止为静态内容触发 ASP.NET 模块
【发布时间】:2012-10-15 04:04:26
【问题描述】:

我在 ASP.NET MVC 应用程序中有一个模块。该模块工作正常,但它会触发包括静态内容在内的每种类型的文件,即使我有:

<modules  runAllManagedModulesForAllRequests="false">
    <add name="MyModule" ... / >
</modules>

该模块挂钩 AcquireRequestState 和 PostRequestHandlerExecute 事件,并且都显示静态内容触发(.htm、.css、.png 等)。

我的印象是 runAllManagedModulesForAllRequests="false" 应该阻止模块在非 ASP.NET 内容上触发。

澄清一下:

可以这样设置 preCondition="managedHandler":

<add name="MyModule" type="MyApp.MyModule" preCondition="managedHandler" />

让我的模块只触发托管请求。

但是,我试图理解为什么 IIS 管道通常会为每个请求触发托管模块命中。我认为这在旧版本中工作得很好,除非 runAllManagedModulesForAllRequests="true" 它不会将非托管内容触发到 ASP.NET 模块中。

在 Windows 8 64 位模式下的 IIS8 上运行,具有集成管道模式。

更新:

经过更多研究,事实证明以下内容是正确的:

  • 如果 runAllManagedModulesForAllRequests="true" 所有模块 - 无论它们的 preCondition 属性设置如何在所有请求上触发。这对于在 HttpApplication 上实现的 Application_XXXX 事件也是如此
  • runAllManagedModulesForAllRequests="false" 无法阻止非托管请求命中模块,除非 preCondition="managedHandler" 已设置
  • runAllManagedModulesForAllRequests="false" 确实会影响 Application_XXXX 事件,从而导致这些事件仅在托管请求上触发。 IOW,Application_XXXX 的行为就好像“模块”实现有一个 preCondition="managedHandler"

有关这方面的更多详细信息,我发布了一篇博客文章: http://www.west-wind.com/weblog/posts/2012/Oct/25/Caveats-with-the-runAllManagedModulesForAllRequests-in-IIS-78

【问题讨论】:

  • 你能检查下StaticFileModule注册在modules下吗?应该指向 %windir%\System32\inetsrv\static.dll
  • 只是为了进行健全性检查,您可以使用 节点的完整祖先进行更新吗?应该在 下。就像我说的,健全性检查。 :)
  • 另外,如果我没记错的话,模块需要 preCondition="managedHandler" -> 添加
  • @pbz - 静态文件模块指向 ISAPI 路径是的。 Drew - 我在 IIS 的模块列表中看不到任何“奇怪”的东西。我删除了 MVC 路由处理程序(无扩展,UrlRouting)以防万一但结果相同。
  • 在我看来,IIS 8 无论如何都在通过托管管道运行每个请求。我什至可以使用 Response.Write() 修改 default.htm 内容,这似乎表明 .htm 文件正在通过 ASP.NET 管道并使用 ASP.NET 响应。如果我重命名为 default.asp,我仍然会触发该模块,但 Response.Write() 可能没有效果,可能是因为 ASP 经典使用其自己的基于 ISAPI 的输出。

标签: asp.net iis


【解决方案1】:

在 IIS7 中,Microsoft 引入了一种使用托管 (.NET) 代码(而不仅仅是本机代码)开发模块和处理程序的新方法。问题是在托管代码和本机代码之间切换请求非常昂贵,因此微软引入了preCondition="managedHandler"。它将模块标记为仅可用于托管内容请求(.aspx、.asmx、...),因此 IIS 避免为静态内容触发它。

现在,您可能需要修改静态内容请求,例如动态缩小 JavaScript。您可以使用 C# 编写模块并将其编译为托管模块,但您希望它针对静态内容被触发,因此您只需不要将其标记为 managedHandler

最后,runAllManagedModulesForAllRequests="true" 被用来覆盖preCondition="managedHandler",所以他们都被解雇了。

更多信息请访问:
http://www.iis.net/learn/get-started/introduction-to-iis/iis-modules-overview#Precondition

【讨论】:

  • Sam - 据我了解,IIS 不会自动触发托管代码。但我怀疑这现在可能是真的 - 一旦任何托管模块在管道上,它可能就会开始为所有请求触发。我更关心性能而不是事物的逻辑。静态内容触发到托管管道这一事实似乎会给一般请求增加大量开销。
猜你喜欢
  • 2018-02-12
  • 2016-07-19
  • 1970-01-01
  • 2011-06-03
  • 2016-11-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-25
相关资源
最近更新 更多