无法将HttpHandler映射到"path/*"通配符映射

25

我一直在尝试将一个http模块映射到MVC3站点的子路径。据我所知,这应该非常简单,但是它并没有起作用。该模块的设置如下:

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

为了在webdev.webserver下运行,iis6也提供了匹配部分。然而,我尝试将其部署到本地Win7的iis7中,以及使用webdev.webserver进行测试,但只有/api实际调用了处理程序。当我调用/api/{anything}时,它只返回404。

我确定我只是"做错了(tm)",但任何帮助都将不胜感激。

注意:我还尝试了其他一些配置,包括使用<location>标签创建/api文件夹,并在该文件夹中添加一个具有完全通配符的web.config。

3个回答

20

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

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

这将匹配:

/api/{任何内容}


1
@ChrisNicola 我在我的API的所有HttpHandlers中都使用这个。完美运行。 - ThinkingStiff
2
这是我认为最好的答案。 - JDC
由于某些原因,这与静态文件处理程序不兼容。该处理程序需要采用所接受答案中所示的方法。 - Roman Starkov
1
这对我起作用了——从一个处理程序(我在其中动态调整/流式传输)提供JPG,从第二个处理程序提供JS / PNG /等等。 - Bill Gillingham
@threed - 在 system.webServer 下我有: <handlers> <remove name="ImageHandler"/> <add name="StaticHandler" path="content" verb="*" type="staticHandler" resourceType="Unspecified" preCondition="integratedMode"/> <add name="artDealer" path="*.jpg" verb="*" type="ArtDealer" resourceType="Unspecified" preCondition="integratedMode"/> </handlers> - Bill Gillingham
显示剩余3条评论

14
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中,您可以在处理程序映射下选择查看有序列表,它将列出加载处理程序的顺序,从上(第一个)到下(最后一个)。

您可能需要在/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 中的 <location> 下再次尝试。 - Chris Nicola
非常接近我所需的。但是由于它被命名为UrlRoutingModule-4.0,它是一个模块而不是处理程序。我已经使用了适合我的正确web.config编辑了您的答案。谢谢你的帮助! - Chris Nicola
实际上,即使进行了这些更改,它仍然不太起作用。我试着调整了一下,但是只有在完全禁用MVC路由的情况下才能让它工作,这并不理想。你说你已经让静态文件路由正常工作了,你能否请再次检查一下你在web.config中所做的内容? - Chris Nicola
好的,既然它对你有效,我会暂时将其标记为答案。我现在对我的解决方案感到满意,而且这个问题太疯狂了,不想再浪费时间了。非常感谢你的帮助。 - Chris Nicola
好的,我已经尝试了几个小时。在子目录中使用不同的web.config文件的想法是完美的。谢谢!看起来在功能上相当于IIS6中的adsutil.vbs SET /W3SVC/105364569/root/Content/ScriptMaps ""。 - penderi
一个位于单独文件夹中的web.config对我很有用,我不需要使用inheritInChildApplications技巧,只需在文件夹的web.config中清除所有处理程序即可。 - Chris S

9

似乎UrlRoutingModule-4.0带来了比它值得的更多麻烦。因此,我已经告诉MVC3忽略这些路由。虽然不是完美的解决方案,但在找到更好的方法之前,我必须坚持在RegisterRoutes中使用它:

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

看起来运行得很好。你发现用这种方式有什么缺点吗? - terjetyl
到目前为止,我已经在生产环境中使用它相当长的一段时间了。 - Chris Nicola
1
如果您正在使用Nancy v0.10+以启用诊断功能,您可能还需要添加routes.IgnoreRoute("_Nancy/{*route}");。 - prabir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接