1

我有这样的路由设置,以允许我的 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 并没有这样看。我究竟做错了什么?

4

3 回答 3

1

只是为了给大家一个更新,我已经放弃尝试使用传统的 webapi 路由来做到这一点。我已经使用 attributerouting.net 采用基于属性的路由,因为它似乎是大多数人都在推动解决这个问题的解决方案。我之所以做出决定,主要是因为 attributerouting.net 功能正在被纳入 VS2013 版本的 WebAPI 2 中。语法略有不同,但功能几乎完全相同。这是一个巨大的进步。甚至 stackoverflow 也将它用于他们的路线,这更加坚定了我的决定。

于 2013-08-30T13:36:02.860 回答
1

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

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

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

[ActionName("assignrole")]
public UserModel PutAssignRole(int id2, RoleModel model)
{
    ...
}
于 2013-08-29T07:34:52.107 回答
0

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

config.Routes.MapHttpRoute("DefaultApiWithIdAndAction", 
     "{controller}/{id}/{action}", 
     null, 
     new { id = @"\d+", action="assignrole" });
于 2013-08-28T21:56:55.000 回答