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

时间:2015-05-27 10:36:25

标签: 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">

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

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

.NET版本

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

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

我们的一些生产代码在.csproj文件中定位.NET4.5但在web.config中没有<compilation targetFramework="4.0"(并且没有<httpRuntime>元素)并且似乎处理更复杂的路由,最后一个参数中的一段时间。

两种情况

使用默认路线:

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

ValuesController进行简单的操作:

public string Get(string id)
{
    return string.Format("Param id: '{0}'", id);
}

请求/api/values/dog.cat,路由将带您进入操作。

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

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

并修改ValuesController中的端点:

public string Get(string category, string id)
{
    return string.Format("category: {0}, id: {1}", category, id);
}

请求/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> 

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

<httpRuntime relaxedUrlToFileSystemMapping="true" />

可能的解决方法

可以降级到.NET4.0,这似乎有效。但是由于使用了异步/等待功能,我们不想这样做。

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

1 个答案:

答案 0 :(得分:5)

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

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