最终参数中包含句点的WebAPI路由失败

App*_*ere 4 asp.net-web-api asp.net-web-api-routing

问题

使用WebAPI,其中请求中的最后一个参数包含句点/句号 /'.'.

  • 对于像/api/values/dog.cat这样的"简单"路线,路线确定.
  • 对于像/api/values/mammal/dog.cat这样的更复杂的路线,返回404

我的问题是如何让更复杂的路线工作?


背景

下面的所有测试都使用从Visual Studio WebAPI模板创建的新项目.

我知道我的请求看起来像是有文件扩展名所以设置:

<modules runAllManagedModulesForAllRequests="true">
Run Code Online (Sandbox Code Playgroud)

因此,在StaticFile处理程序未找到该项之后,它会将其传递给托管处理程序.

如果我请求/api/values/mamal/dog.cat/(带有斜杠)这样可以正常工作,但不幸的是我们仍然坚持使用API​​合同而我无法做到这一点.

.NET版本

当以.NET4.0为目标并使用Visual Studio WebAPI模板时,更复杂的路由可以正常工作.

使用默认WebAPI模板定位.NET4.5时,更复杂的路由返回404.

我们的一些生产代码是在.csproj文件中以.NET4.5为目标,但<compilation targetFramework="4.0"在web.config中(并且没有<httpRuntime>元素)并且似乎处理更复杂的路由,在最终参数中有句点.

这两个场景

使用默认路由:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
Run Code Online (Sandbox Code Playgroud)

一个简单的动作ValuesController:

public string Get(string id)
{
    return string.Format("Param id: '{0}'", id);
}
Run Code Online (Sandbox Code Playgroud)

请求/api/values/dog.cat和路由将您带到操作.

现在更改路线以添加其他类别参数:

config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{category}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
Run Code Online (Sandbox Code Playgroud)

并在以下位置修改端点ValuesController:

public string Get(string category, string id)
{
    return string.Format("category: {0}, id: {1}", category, id);
}
Run Code Online (Sandbox Code Playgroud)

请求/api/values/mamal/dog.cat,你得到404 not found.

请求/api/values/mamal/dog.cat/和操作被调用.

其他stackoverflow问题

stackoverflow上有各种类似的问题,它们的答案看起来像是在解决这个问题,但实际上并不相关(如果您考虑将此问题标记为重复!).

例如:

此处理程序仅处理以句点结尾的请求,例如/api/values/dog.cat.,并且不处理参数中的句点:

<system.webServer>
  <handlers>
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
   </handlers>
</system.webServer> 
Run Code Online (Sandbox Code Playgroud)

此外,以下映射仅涉及允许保留字,而不是URL中的句点:

<httpRuntime relaxedUrlToFileSystemMapping="true" />
Run Code Online (Sandbox Code Playgroud)

可能的解决方法

可以降级到.NET4.0,这似乎有效.但是由于使用async/await功能,不想这样做.

我可能会使用IIS URL Rewrite模块之类的东西为缺少它的请求添加一个尾部斜杠,但我宁愿找到一个基于理解为什么绑定"失败"的解决方案.

Joe*_* V. 5

通过修改web.config处理程序部分和路径属性解决此问题,将其从path ="*"更改.to path ="*"

<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*" verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />