Web.API MapHttpRoute参数

我的Web.API路由有问题。 我有以下两条路线:

config.Routes.MapHttpRoute( name: "MethodOne", routeTemplate: "api/{controller}/{action}/{id}/{type}", defaults: new { id = RouteParameter.Optional, type = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "MethodTwo", routeTemplate: "api/{controller}/{action}/{directory}/{report}", defaults: new { directory = RouteParameter.Optional, report = RouteParameter.Optional } ); 

在我的控制器中这两种方法:

 [HttpGet] [ActionName("methodone")] public string MethodOne(string id, string type) { return string.Empty; } [HttpGet] [ActionName("methodtwo")] public string MethodTwo(string directory, string report) { return string.Empty; } 

这两个看似不能并存。 如果我在WebApiConfig中注释掉MethodOne路由,则MethodTwo路由可以工作。 评论MethodTwo路由允许MethodOne工作。 留下两个未注释的,MethodOne可以工作,但不是MethodTwo。

我希望为这两个路由使用一个路由,然后它们似乎必须具有相同的参数名称。 谁用通用参数名称编写方法? 坏。 我真的不希望我的方法具有相同的参数名称(如p1,p2,p3),所以我想我可以为新方法创建一个路径。 但即使这样似乎也行不通。

我真的很想念WCFrest的WebGet(UriTemplate="")

我有一个控制器有很多方法,一些有1,2,3或甚至更多的参数。 我无法相信我无法使用MapHttpRoute方法使用有意义的参数名称。

我可以完全评论这些东西并使用WebGet() ……但在我到达那里之前,我想看看我是否遗漏了一些东西。

您遇到此问题的原因是您的第一个路由将匹配两个请求。 URL中的id和类型标记将匹配两个请求,因为在运行路由时,它将尝试解析URL并将每个段与您的URL匹配。

因此,您的第一条路线将很乐意匹配两个请求,如下所示。

 ~/methodone/1/mytype => action = methodone, id = 1, and type = mytype ~/methodtwo/directory/report => action = methodtwo, id = directory, and type = report 

要解决这个问题,你应该使用类似的路线

 config.Routes.MapHttpRoute( name: "MethodOne", routeTemplate: "api/{controller}/methodone/{id}/{type}", defaults: new { id = RouteParameter.Optional, type = RouteParameter.Optional } ); config.Routes.MapHttpRoute( name: "MethodTwo", routeTemplate: "api/{controller}/methodtwo/{directory}/{report}", defaults: new { directory = RouteParameter.Optional, report = RouteParameter.Optional } ); 

即使您使用WebGet,您也可能需要做类似的事情来消除我认为的两种方法的歧义。

您可以选择在查询字符串中传递参数,例如/ MethodTwo?directory = a&report = b,但是如果您希望它们显示在路径中,则这看起来像是基于属性的路由的良好候选。 菲利普在这里有一篇很棒的post:

http://www.strathweb.com/2012/05/attribute-based-routing-in-asp-net-web-api/

来自http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection

您还可以提供约束,这些约束限制URI段与占位符匹配的方式:

constraints:new {id = @“\ d +”} //仅当“id”是一个或多个数字时才匹配。

将此约束添加到“MethodOne”(api / {controller} / {action} / {id} / {type})将意味着只有{id}是数字才能匹配的数字,否则它将匹配“MethodTwo”(“api” / {控制器} / {行动} / {目录} / {报告}“)。