致电
http://mysite.com/Project/42
对于下面的路由和方法,我得到一个“找到了匹配请求的多个动作... Get(Int32)... Children(Int32)”
打电话
http://mysite.com/Project/42/Children
正确返回。
我的路由是:
config.Routes.MapHttpRoute(
name: "ForChildren",
routeTemplate: "api/{controller}/{id}/Children",
defaults: new { action = "Children" }
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
我的方法:
public class ProjectController : ApiController {
public IEnumerable<Project> Get(int id){
...
}
[HttpGet]
public IEnumerable<Project> Children(int id) {
...
}
}
我认为不指定该操作会导致Webapi默认为方法(GET)。现在看起来Webapi正在运行这些方法而忽略了它们的名称,只是寻找参数匹配。我真的不相信,认为我在其他地方有过错。
答案 0 :(得分:1)
这是行动选择当前在Web API中的工作方式的已知行为/问题。在您的请求为“http://mysite.com/Project/42”的情况下,请求与“DefaultApi”路由匹配,并且在操作选择期间,操作选择器没有require变量“action”的值,因此它尝试从可通过GET方法获得的可用操作列表。它试图根据路由参数(如'id'在这里)和查询字符串参数找出se中的最佳动作。在您的场景中,操作选择器会看到2个获取操作,每个操作都接受id参数,因此在选择它们时会看到歧义。
此处提交的问题与您的方案类似: http://aspnetwebstack.codeplex.com/workitem/184
答案 1 :(得分:1)
一个简单的解决方案是只有一条路线:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}/{action}",
defaults: new { id = RouteParameter.Optional, action = "DefaultAction" }
);
然后装饰你的默认动作:
public class ProjectController : ApiController {
[ActionName("DefaultAction")]
public IEnumerable<Project> Get(){
// api/project
// Return all projects
}
[HttpGet]
public IEnumerable<Project> Children(int id) {
// api/project/1/children
// Return children of project with id == 1
}
}
答案 2 :(得分:0)
在Web API 2中,您可以使用属性路由:
[RoutePrefix("Project")]
public class ProjectController : ApiController {
[Route("{id:int}")]
public IEnumerable<Project> Get(int id){
...
}
[HttpGet]
[Route("{id:int}/Children")]
public IEnumerable<Project> Children(int id) {
...
}
}