【发布时间】:2018-02-06 14:43:19
【问题描述】:
背景
我有一个控制器
public class WorkOrderController : ApiController
{
// GET: api/WorkOrder
public IEnumerable<WhateverObj> Get()
{
//etc..
}
// GET: api/WorkOrder/123
public WhateverObj Get(string id)
{
//etc..
}
// GET: api/WorkOrder/5/020
public WhateverObj Get(string id, string opID)
{
//etc...
}
}
以及以下路线:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "ServicesApi",
routeTemplate: "api/{controller}/{id}/{opID}",
defaults: new { opID = RouteParameter.Optional }
);
这按预期工作,我可以导航到上面的示例 URL。
问题
现在我想用一种方法创建另一个控制器,如下所示:
public class FilteredWorkOrderController : ApiController
{
//By WorkCentreID = ABC, XYZ, UVW
public IEnumerable<WhateverObj> Get(string workCentreID)
{
//etc...
}
}
下面的网址点击上面的方法ok。
http://localhost:62793/api/FilteredWorkOrder/?workCentreID=ABC
但是(替代)形式
http://localhost:62793/api/FilteredWorkOrder/ABC
不起作用,错误信息是:
{"Message":"找不到与请求 URI 'http://localhost:62793/api/FilteredWorkOrder/ABC'匹配的 HTTP 资源。","MessageDetail":"在控制器 'FilteredWorkOrder' 上找不到与请求匹配的操作。"}
我需要什么路由映射配置才能使替代 URI 也可以工作?
我试过了
config.Routes.MapHttpRoute(
name: "FilteredApi",
routeTemplate: "api/{controller}/{workCentreID}"
);
但这不起作用。
我注意到在 Filtered 控制器中,如果我将 Get(string workCenterID) 中的参数名称更改为 Get(string id),那么两个 URL 都可以工作!
http://localhost:62793/api/FilteredWorkOrder/?id=ABC
http://localhost:62793/api/FilteredWorkOrder/ABC
参数名有什么神奇之处:'id'?
我希望我的参数被称为workCentreID。
【问题讨论】:
-
你研究过属性路由吗?这些天我倾向于使用它,因为它使路由接近受影响的代码。 docs.microsoft.com/en-us/aspnet/web-api/overview/…
-
检查路线的顺序。更通用的路由应该出现在更有针对性或专门的路由之后,否则通用路由将捕获并处理用于其他路由的请求。因此,在您的情况下,您需要切换当前注册的路由的顺序,或者另一种选择是考虑使用属性路由参考Attribute Routing in ASP.NET Web API 2