19

我有Users控制器,基本的 REST 模式工作得很好。但是,我需要一种额外的模式users/{id}/usergroups来返回该用户的所有用户组。

实现这一点的最佳方法是什么,因为我想我将需要在更多控制器上使用类似的路由。只是默认的还不够...

错误

找到了与请求匹配的多个操作:Api.Models.Users.User GetUser(Int32) on type Api.Controllers.UsersController System.Collections.Generic.IEnumerable`1[Api.Models.Users.UserGroup] GetUserGroups(Int32) on输入 Api.Controllers.UsersController

代码

// GET api/Users
public IEnumerable<User> GetUsers()

// GET api/Users/5
public User GetUser(int id) // THIS IS CONFLICT 1

// PUT api/Users/5
public HttpResponseMessage PutUser(int id, User user)

// POST api/Users
public HttpResponseMessage PostUser(User user)

// DELETE api/Users/5
public HttpResponseMessage DeleteUser(int id)

// GET api/Users/5/UserGroups
public IEnumerable<UserGroup> GetUserGroups(int id)  // THIS IS CONFLICT 2

编辑 1

按照amhed的建议做了,并没有解决问题。

// GET api/Users/5
[HttpGet, ActionName("getuser")]
public User GetUser(int id) // THIS STILL DOES NOT WORK

// GET api/Users/5/UserGroups
[HttpGet, ActionName("usergroups")]
public IEnumerable<UserGroup> GetUserGroups(int id) // THIS WORKS

// ROUTES
config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "{controller}/{id}/{action}",
    defaults: new { id = RouteParameter.Optional, action = RouteParameter.Optional }
);
4

2 回答 2

19

您可以:只定义一个Get方法,并有一个可选的 Id 参数,如下所示:

public IEnumerable<User> GetUsers(int? id){
    if (id.HasValue)
    {
         //return collection of one item here
    }
    //return collection of all items here
}

或者您可以使用 ActionName 属性装饰多个 Get

// GET api/Users
[ActionName("GetAll")]
public IEnumerable<User> GetUsers()

// GET api/Users/5
[ActionName("Get")]
public User GetUser(int id) // THIS IS NO LONGER IN CONFLICT

然后在 RouteConfig 上定义路由,如下所示:

routes.MapHttpRoute(
            name: "DefaultApiWithAction",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
            );
于 2013-07-07T12:13:38.120 回答
1

我被困在使用 Web API v1 并提出了以下解决方案。对于所有常规路线,将 ActionName 声明为“默认”。然后在您的路由配置中,设置默认操作 =“默认”。这会将您对 /Users/5 的调用更改为 users/5/default 并确保它映射到正确的位置。我发现这个解决方案的唯一问题是文档将显示路由的 /Default 部分。看起来您可以像这个人一样编辑您的视图以排除这些(https://stackoverflow.com/a/29353198/4374666)。

如果您使用的是 v2,那么属性路由似乎是最干净的方式。

// GET api/Users/5
[HttpGet, ActionName("Default")]
public User GetUser(int id) // THIS STILL DOES NOT WORK

// GET api/Users/5/UserGroups
[HttpGet, ActionName("usergroups")]
public IEnumerable<UserGroup> GetUserGroups(int id) // THIS WORKS

// ROUTES
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "{controller}/{id}/{action}",
    defaults: new { id = RouteParameter.Optional,
 action = "Default" }
);
于 2015-11-04T22:10:44.037 回答