发现多个操作将请求与多个PUT webapi操作匹配

时间:2013-08-28 21:21:24

标签: asp.net-mvc-4 asp.net-web-api duplicates asp.net-mvc-routing

我的路由设置如下,以便为我的webapi控制器提供基于动作的路由:

config.Routes.MapHttpRoute("DefaultApiWithIdAndAction", "{controller}/{id}/{action}", null, new { id = @"\d+" });
config.Routes.MapHttpRoute("DefaultApiWithId", "{controller}/{id}", null, new {id = @"\d+"});
config.Routes.MapHttpRoute("DefaultApiWithAction", "{controller}/{action}");
config.Routes.MapHttpRoute("DefaultApiGet", "{controller}", new { action = "Get" }, 
    new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) });
config.Routes.MapHttpRoute("DefaultApiPost", "{controller}", new {action = "Post"}, 
    new {httpMethod = new HttpMethodConstraint(HttpMethod.Post)});

以下是我想要支持的所有类型的路线。除了没有动作的默认PUT,它们都可以工作。由于某种原因,基于行动的PUT请求工作正常。

GET  users
GET  users/1
POST users
PUT  users/1             <- thinks its a duplicate route
PUT  users/1/assignrole  <- of this route even though this one works
DEL  users/1

以下是我定义控制器操作的方法:

public UserModel Put(int id, UserModel model)

[ActionName("assignrole")]
public UserModel PutAssignRole(int id, RoleModel model)

我会认为它们是不同的,因为动作名称不同但是mvc没有这样看。我做错了什么?

3 个答案:

答案 0 :(得分:1)

您需要区分这两种方法的签名。将您的第一条路线改为:

config.Routes.MapHttpRoute("DefaultApiWithIdAndAction",
    "{controller}/{id2}/{action}",
    null,
    new { id2 = @"\d+" });

然后将您的第二个操作更改为:

[ActionName("assignrole")]
public UserModel PutAssignRole(int id2, RoleModel model)
{
    ...
}

答案 1 :(得分:1)

为了给你所有更新,我放弃了尝试使用传统的webapi路由。我使用attributerouting.net采用了基于属性的路由,因为它似乎是大多数人都在努力解决这个问题的解决方案。我做出了自己的决定,因为attributerouting.net功能正在进入VSAP13版本的WebAPI 2。语法略有不同,但功能几乎完全相同。它的改进很大。甚至stackoverflow也将它用于他们的路线,这有助于巩固我的决定。

答案 2 :(得分:0)

您可以尝试将第一个路由定义限制为仅接受这一个操作,因为它似乎不会用于任何其他路由:

config.Routes.MapHttpRoute("DefaultApiWithIdAndAction", 
     "{controller}/{id}/{action}", 
     null, 
     new { id = @"\d+", action="assignrole" });