WebApi — несколько действий GET с одинаковыми подписями — проблема с маршрутизацией

Предыстория вопроса:

У меня есть один контроллер в моем WebApi, который имеет два метода действий. Эти два метода действий являются методами GET и не имеют параметров.

Один метод действия называется «GetMessages», другой — «GetEmployeeList».

Проблема:

Это следующие методы действий в моем контроллере:

[HttpGet]
public string GetMessages()
{
  return "Get Messages Endpoint";
}

[HttpGet]
public string GetEmployeeList()
{
    return "Get Employees Endpoint";
}

Это таможенные маршруты, которые я установил с помощью WepApiConfig.

  config.Routes.MapHttpRoute(
  name: "Messages",
  routeTemplate: "v2/api/People/{action}/{id}",
  defaults: new { action = "GetMessages", id = RouteParameter.Optional });


   config.Routes.MapHttpRoute(
   name: "Employees",
   routeTemplate: "v2/api/People/{action}/{id}",
   defaults: new { action = "GetEmployeeList", id = RouteParameter.Optional});

Когда я вызываю любой из следующих URL-адресов pf:

/v2/api/People/GetMessages
/v2/api/People/GetEmployeeList

Я получаю следующее сообщение об исключении, в котором говорится, что несколько действий соответствуют запросу URL:

Multiple actions were found that match the request: System.Net.Http.HttpResponseMessage GetMessages() on type Persons.PeopleController System.Net.Http.HttpResponseMessage GetEmployeeList() on Persons.PeopleController

Как я могу исправить это, чтобы использовать два метода действия GET вместе, которые имеют одинаковую подпись?


person user1352057    schedule 29.06.2016    source источник
comment
Проверьте мой ответ здесь: title="rest web api 2 вызывает метод призыва к действию без вызова"> stackoverflow.com/questions/37608637/   -  person Marcus Höglund    schedule 29.06.2016


Ответы (3)


Возможно, я не понимаю, но почему бы вам просто не настроить маршруты следующим образом (обратите внимание на имена действий в шаблонах маршрутов):

config.Routes.MapHttpRoute(
  name: "Messages",
  routeTemplate: "v2/api/People/GetMessages/{id}",
  defaults: new { action = "GetMessages", id = RouteParameter.Optional });

config.Routes.MapHttpRoute(
   name: "Employees",
   routeTemplate: "v2/api/People/GetEmployeeList/{id}",
   defaults: new { action = "GetEmployeeList", id = RouteParameter.Optional});

Однако я бы предпочел более общий вариант:

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

Таким образом, вы можете охватить оба действия одним маршрутом. Есть ли причина не выбирать этот вариант?

person Anton    schedule 29.06.2016

Вам не нужно иметь два маршрута. Одного достаточно. Попробуйте изменить маршрут на следующий.

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

Вы можете попытаться указать свои маршруты отдельно, но это не обязательно. Убедитесь, что ваш вызов веб-API на 100 % правильный.

person fjompen    schedule 29.06.2016

Как насчет указания маршрута для каждого метода отдельно?

[RoutePrefix("api/people")]
public class MyController : ApiController
{
    [HttpGet]
    [Route("messages")]
    public string GetMessages()
    {
      return "Get Messages Endpoint";
    }

    [HttpGet]
    [Route("employees")]
    public string GetEmployeeList()
    {
        return "Get Employees Endpoint";
    }
}    

поэтому у вас будут такие URL-адреса, как

/v2/api/people/messages
/v2/api/people/employees

который IMHO выглядит немного более RESTful, чем ваш пример

person Václav Holuša    schedule 29.06.2016