Подтвердить что ты не робот

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 }
);
4b9b3361

Ответ 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" }
);