无法将 HttpHandler 映射到“路径/*”通配符映射

Posted

技术标签:

【中文标题】无法将 HttpHandler 映射到“路径/*”通配符映射【英文标题】:Unable to map an HttpHandler to a "path/*" wildcard mapping 【发布时间】:2011-08-21 23:55:13 【问题描述】:

所以我一直在尝试将 http 模块映射到 MVC3 站点的子路径。据我了解,它应该很简单,但它一直没有工作。模块设置如下:

<handlers>
  <add name="Nancy" path="api/*" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" allowPathInfo="true" />
</handlers>

iis6 也有一个匹配部分,因此我可以在 webdev.webserver 下运行它。然而,测试部署到我的本地 iis7(在 Win7 下)和使用 webdev.webserver,只有 /api 实际调用处理程序。如果我调用 /api/anything 它只会返回 404。

我确定我只是“做错了 (tm)”,但我们将不胜感激。

注意:我还尝试了其他一些配置,包括使用标签和创建 /api 文件夹,以及使用完整的通配符将 web.config 添加到该文件夹​​。

【问题讨论】:

【参考方案1】:

简单。只需输入路径,不要使用通配符。

<handlers>
  <add name="Nancy" path="api" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" allowPathInfo="true" />
</handlers>

这将匹配:

/api/任何东西

【讨论】:

有趣,我不再做 .NET 工作了,所以我可能没有时间验证这一点。如果其他人可以,我很乐意将其标记为正确答案。老实说,这似乎几乎……太容易了。我必须相信我会尝试的。 @ChrisNicola 我将它用于我所有的 API HttpHandlers。完美运行。 这是我认为最好的答案。 由于某种原因,这不适用于静态文件处理程序。此处理程序需要接受的答案中显示的方法。 这个确实对我有用 - 从一个处理程序(我动态调整大小/流)和第二个处理程序提供 js/png/etc。【参考方案2】:

URLRoutingModule-4.0 是在您的 nancy 处理程序之前列出的全部处理程序。因此,它会在你的处理程序被击中之前发挥作用。您可以删除添加您的处理程序并将它们重新添加,如下所示:

<handlers>
    <remove name="BlockViewHandler" />
    <remove name="UrlRoutingModule-4.0" />
    <add verb="*" path="robots.txt" name="robots" type="System.Web.StaticFileHandler"/>
    ... custom handlers here
    <add name="Nancy" path="api/*" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" allowPathInfo="true" />
    ... now add back UrlRoutingModule and BlockViewHandler
    <add path="*" verb="*" name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" preCondition="managedHandler" />
    <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" /> 
</handlers>

您可以在 IIS7 中的 Handler Mappings 下选择 View Ordered List 看到处理程序的顺序,它会列出加载处理程序的顺序,从上到下(最后)。

您可能需要在 /api 文件夹中添加第二个 Web.config

<?xml version="1.0"?>
<configuration>
    <system.web>
      <httpHandlers>
        <clear />
        <add name="Nancy" path="*" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" allowPathInfo="true" />
      </httpHandlers>
    </system.web>
</configuration>

同样,这也是我通常对网站上的“/static”内容执行的操作。我还没有发现如何规避对秒 web.config 的需要。

编辑

当我不得不这样做时,我很难弄清楚这一点,而且似乎我的记忆对我没有帮助。我没有在任何地方指定path/* 处理程序,而是我有这个:

(仅指定简单的通配符/完全限定的路径来绕过 UrlRouting)

<location path="." inheritInChildApplications="false">
    <system.webServer>
        <!--
        ml: in .NET 4.0 its now safe to remove  from the modules section.
        Make sure you have a *. mapping to a ExtensionLessUrl hanlder in IIS
        this should improve performance a tad albeit neglectable.

        see: http://blogs.msdn.com/b/tmarq/archive/2010/04/01/asp-net-4-0-enables-routing-of-extensionless-urls-without-impacting-static-requests.aspx
        -->

        <validation validateIntegratedModeConfiguration="false" />
        <modules runAllManagedModulesForAllRequests="false" />
        <handlers>
            <remove name="BlockViewHandler" />
            <remove name="UrlRoutingModule-4.0" />
            <add verb="*" path="robots.txt" name="robots" type="System.Web.StaticFileHandler"/>
            .. Some company handlers i can't list 
            <add path="*" verb="*" name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" preCondition="managedHandler" />
            <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
        </handlers>
    </system.webServer>
</location>

然后在我的/Content/web.config 文件中设置以下内容:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <handlers>
            <clear />
            <add name="StaticFiles" path="*" verb="*" modules="StaticFileModule" resourceType="Either" requireAccess="None" />
        </handlers>
        <staticContent>
            <clientCache cacheControlMaxAge ="31.00:00:00" cacheControlMode="UseMaxAge" />
        </staticContent>
    </system.webServer>
</configuration>

/Content/ 的处理程序列表现在看起来像这样:

我可以肯定的是,/Content/ 中的任何内容都将通过 StaticFileModule 提供。这里的技巧似乎是指定:inheritInChildApplications="false"

【讨论】:

我已经尝试了很多组合,但它似乎在 IIS6 或 IIS7 下不起作用。结果相同。我在 /api 文件夹和主 web.config 中的第二个 Web.config 下的 下再次尝试了该操作 非常接近我的需要。但正如它所命名的 UrlRoutingModule-4.0 是一个模块而不是一个处理程序。我已经使用对我有用的正确 web.config 编辑了您的答案。感谢您的帮助! 实际上,即使进行了这些更改,这也不太奏效。我摆弄它,我只能通过完全禁用 MVC 路由来让它工作,这并不理想。你说你已经为静态文件路由工作了,请你仔细检查一下你在 web.configs 中做了什么。 好的,既然它对你有用,我会暂时将其标记为答案。我现在对下面的解决方案没问题,再玩这个问题简直太疯狂了。非常感谢您的帮助 好人。我已经尝试了几个小时。子目录上不同的 web.config 的想法是完美的。谢谢!!似乎在功能上等同于 IIS6 的 adsutil.vbs SET /W3SVC/105364569/root/Content/ScriptMaps ""【参考方案3】:

似乎 UrlRoutingModule-4.0 麻烦多于其价值。相反,我刚刚告诉 MVC3 忽略路由。这不是一个完美的解决方案,但在我有更好的解决方案之前,我必须在RegisterRoutes 中坚持这一点:

routes.IgnoreRoute("api/*route");

【讨论】:

似乎运行良好。你发现这样做有什么缺点吗? 目前还没有,已经在生产中使用了一段时间了。 您可能还想添加路由。IgnoreRoute("_Nancy/*route");如果您使用 nancy v0.10+ 来启用诊断。

以上是关于无法将 HttpHandler 映射到“路径/*”通配符映射的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET路由系统实现原理:HttpHandler的动态映射

问题映射 HttpHandler --> HTTP Error 404 Not Found

osgi (bndtools) 中的 Restlet 包无法启动。激活程序错误 com/sun/net/httpserver/HttpHandler

将 httpHandler 附加到 httpclientFactory webapi aspnetcore 2.1

将 jquery json 传递到 asp.net httphandler

无法加载类型“System.ServiceModel.Activation.HttpHandler”与 WCF REST 的版本冲突