Контроллер API, объявляющий более одного оператора Get

Используя новый контроллер Api в MVC4, я обнаружил проблему. Если у меня есть следующие методы:

public IEnumberable<string> GetAll()

public IEnumberable<string> GetSpecific(int i)

Это сработает. Однако, если я хочу получить некоторые другие данные другого типа, по умолчанию используется метод GetAll, даже если для $.getJSON задан метод GetAllIntegers:

public IEnumberable<int> GetAllIntergers()

(неправильные правила именования)

Возможно ли, чтобы я смог это сделать?

Могу ли я иметь только один метод GetAll в контроллере веб-API?

Я думаю, что легче визуализировать то, чего я пытаюсь достичь. Вот фрагмент кода, показывающий, что я хотел бы сделать в одном ApiController:

public IEnumerable<string> GetClients()
{ // Get data
}

public IEnumerable<string> GetClient(int id)
{ // Get data
}

public IEnumerable<string> GetStaffMember(int id)
{ // Get data
}

public IEnumerable<string> GetStaffMembers()
{ // Get data
}

person Neil Knight    schedule 12.04.2012    source источник


Ответы (2)


Это все есть в маршрутизации. Маршрут веб-API по умолчанию выглядит следующим образом:

config.Routes.MapHttpRoute( 
    name: "API Default", 
    routeTemplate: "api/{controller}/{id}", 
    defaults: new { id = RouteParameter.Optional } 
);

В шаблоне маршрутизации по умолчанию веб-API использует метод HTTP для выбора действия. В результате он сопоставит запрос GET без параметров с первым GetAll, который сможет найти. Чтобы обойти это, вам нужно определить маршрут, в который включено имя действия:

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

После этого вы можете начать делать запросы со следующими URL-адресами:

  • API/yourapicontroller/GetClients
  • API/yourapicontroller/GetStaffMembers

Таким образом, вы можете иметь несколько GetAll в контроллере.

Еще один важный момент заключается в том, что при таком стиле маршрутизации вы должны использовать атрибуты для указания разрешенных HTTP-методов (например, [HttpGet]).

Существует также возможность смешивания маршрутизации на основе глаголов Web API по умолчанию с традиционным подходом, она очень хорошо описана здесь:

person tpeczek    schedule 12.04.2012
comment
Быстрый вопрос, могу ли я маршрутизировать таким образом и по-прежнему вызывать свои методы только Post и автоматически принимать только HttpPost, если я включаю ActionNameAttribute? - person Alxandr; 06.05.2012
comment
@Alxandr Вам все равно придется использовать AcceptVerbsAttribute (или HttpPostAttribute, HttpGetAttribute и т. д.) - person tpeczek; 06.05.2012
comment
У меня проблемы с маршрутизацией — я могу определить несколько методов GET, но если я нажму /api/{controller}, сервер выдаст несколько найденных действий HTTP 500, а не 404. Есть идеи, как это заблокировать? Я бы хотел, чтобы маршрут /api/{controller}/{id} к Get, Post, Put, Delete и т. д., а затем маршрут /api/{controller}/{id}/{action} к определенному действие, например /api/Customers/5/Products. Не работает - все выдает ошибку множественных действий. - person ShadowChaser; 16.05.2012
comment
@tpeczek У меня такая же проблема. Должна ли маршрутизация с дополнительным {action} заменить маршрутизацию по умолчанию или ее следует добавить после нее? - person uriDium; 16.09.2013
comment
@uriDium Похоже, вы ищете сочетание традиционной маршрутизации и маршрутизации на основе глаголов, вы можете узнать больше об этом здесь: blog.appliedis.com/2013/03/25/ - person tpeczek; 16.09.2013
comment
Мой не работает. У меня есть две отдельные функции, однако она возвращает только одну из них. - person Si8; 20.01.2017
comment
@ Si8 Пожалуйста, предоставьте более подробную информацию или свяжитесь со мной по электронной почте - я постараюсь помочь. - person tpeczek; 20.01.2017
comment
@tpeczek Спасибо. Мне пришлось добавить [HttpGet] для каждой функции, и все работало нормально. Спасибо. - person Si8; 20.01.2017

В случае, если кто-то еще сталкивается с этой проблемой. Вот как я решил это. Используйте атрибут [Route] на вашем контроллере для маршрутизации к определенному URL-адресу.

[Route("api/getClient")]
public ClientViewModel GetClient(int id)

[Route("api/getAllClients")]
public IEnumerable<ClientViewModel> GetClients()
person Archna    schedule 03.03.2015
comment
ссылка на атрибут маршрута для тех, кому еще более любопытно, что это за формат: docs.microsoft.com/en-us/aspnet/web-api/overview/ - person Callat; 19.06.2017