ASP.NET WebApi - несколько действий GET в одном контроллере
У меня есть контроллер Users
, а основной шаблон REST работает нормально. Однако мне нужен еще один шаблон users/{id}/usergroups
, который будет возвращать все пользовательские группы для этого пользователя.
Какой был бы лучший способ реализовать это, так как я предполагаю, что мне понадобятся подобные маршруты на многих других контроллерах. Просто по умолчанию их недостаточно...
Error
Было найдено несколько действий, соответствующих запросу: Api.Models.Users.User GetUser (Int32) по типу Api.Controllers.UsersController System.Collections.Generic.IEnumerable`1 [Api.Models.Users.UserGroup] GetUserGroups (Int32) по типу 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
Я сделал то, что предложил, и это не решает проблему.
// 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 }
);
Ответы
Ответ 1
Вы можете: просто определить один метод Get
и указать необязательный параметр Id, например:
public IEnumerable<User> GetUsers(int? id){
if (id.HasValue)
{
//return collection of one item here
}
//return collection of all items here
}
Или вы можете иметь несколько Gets, украшенных атрибутом ActionName
// 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 }
);
Ответ 2
Я застрял с помощью Web API v1 и подошел к следующему решению. Для всех ваших общих маршрутов объявите ActionName как "Default". Затем в конфигурации маршрута установите действие по умолчанию = "По умолчанию". Это изменяет ваш вызов на /Users/ 5 на пользователей/5/по умолчанию и обеспечивает его отображение в нужном месте. Единственная проблема, с которой я столкнулся, заключается в том, что в документации будет показана часть/по умолчанию для маршрута. Похоже, вы можете отредактировать свое мнение, чтобы исключить их, как этот парень (fooobar.com/info/309006/...).
Если вы используете 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" }
);