Было найдено несколько действий, соответствующих запросу в Web Api

Я получаю эту ошибку, когда пытаюсь использовать 2 метода "Get"

Найдено несколько действий, соответствующих запросу: webapi

Я смотрел вокруг на другие подобные вопросы об этом в стеке, но я не понимаю.

У меня есть 2 разных имени и с помощью атрибута "HttpGet"

[HttpGet]
public HttpResponseMessage Summary(MyVm vm)
{
    return null;
}

[HttpGet]
public HttpResponseMessage FullDetails()
{
    return null;
}

14 ответов

Решение

Ваша карта маршрута, вероятно, выглядит примерно так:

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

Но чтобы иметь несколько действий с одним и тем же методом http, вам нужно предоставить webapi больше информации по маршруту, например:

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

Обратите внимание, что routeTemplate теперь включает в себя действие. Много дополнительной информации здесь: http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

Обновить:

Хорошо, теперь, когда я думаю, что я понимаю, что вы после здесь, еще один взгляд на это:

Возможно, вам не нужен параметр action url, и вы должны описать содержимое, которое вам нужно, другим способом. Поскольку вы говорите, что методы возвращают данные из одной и той же сущности, просто позвольте параметрам описать вас.

Например, ваши два метода могут быть превращены в:

public HttpResponseMessage Get()
{
    return null;
}

public HttpResponseMessage Get(MyVm vm)
{
    return null;
}

Какие данные вы передаете в объект MyVm? Если вы можете просто передавать переменные через URI, я бы предложил пойти по этому пути. В противном случае вам нужно будет отправить объект в теле запроса, и это не очень HTTP с вашей стороны при выполнении GET (хотя это работает, просто используйте [FromBody] перед MyVm).

Надеюсь, это показывает, что вы можете иметь несколько методов GET в одном контроллере без использования имени действия или даже атрибута [HttpGet].

Обновление с веб-API 2.

С помощью этой конфигурации API в вашем файле WebApiConfig.cs:

public static void Register(HttpConfiguration config)
{
    //// Web API routes
    config.MapHttpAttributeRoutes(); //Don't miss this

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

Вы можете направить наш контроллер следующим образом:

[Route("api/ControllerName/Summary")]
[HttpGet]
public HttpResponseMessage Summary(MyVm vm)
{
    rturn null;
}

[Route("api/ControllerName/FullDetails")]
[HttpGet]
public HttpResponseMessage FullDetails()
{
    return null;
}

Где ControllerName - это имя вашего контроллера (без "controller"). Это позволит вам получить каждое действие с маршрутом, описанным выше.

Для дальнейшего чтения: http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

В веб-API (по умолчанию) методы выбираются на основе комбинации метода HTTP и значений маршрута.

MyVm выглядит как сложный объект, считываемый средством форматирования из тела, поэтому у вас есть два идентичных метода с точки зрения данных о маршруте (поскольку ни один из них не имеет параметров из маршрута) - что делает его невозможным для диспетчера (IHttpActionSelector), чтобы соответствовать соответствующему.

Вам нужно различать их либо по строке запроса, либо по параметру маршрута, чтобы устранить неоднозначность.

После долгих поисков в Интернете и попыток найти наиболее подходящую форму для карты маршрутизации, если нашли следующее

config.Routes.MapHttpRoute("DefaultApiWithId", "Api/{controller}/{id}", new { id =RouteParameter.Optional }, new { id = @"\d+" });
config.Routes.MapHttpRoute("DefaultApiWithAction", "Api/{controller}/{action}");

Это отображение применяется как к отображению имени действия, так и к базовому соглашению http (GET,POST,PUT,DELETE)

Это ответ для всех, кто знает, что все правильно и проверил 50 раз.....

Убедитесь, что вы не смотрите повторно RouteConfig.cs,

Файл, который вы хотите редактировать, называется WebApiConfig.cs

Кроме того, это должно выглядеть примерно так:

using System.Web.Http;

namespace My.Epic.Website
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
          config.MapHttpAttributeRoutes();

          // api/Country/WithStates
          config.Routes.MapHttpRoute(
            name: "ControllerAndActionOnly",
            routeTemplate: "api/{controller}/{action}",
            defaults: new { },
            constraints: new { action = @"^[a-zA-Z]+([\s][a-zA-Z]+)*$" });

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

Я мог бы спасти себя около 3 часов.

Без использования действий параметры будут:

  1. переместите один из методов на другой контроллер, чтобы они не конфликтовали.

  2. используйте только один метод, который принимает параметр, и, если он пуст, вызовите другой метод из вашего кода.

Вполне возможно, что ваши веб-методы разрешаются по одному и тому же URL. Посмотрите на следующую ссылку: -

http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-in-aspnet-web-api

Таким образом, вам может потребоваться добавить имя вашего метода в таблицу маршрутизации.

Это решение сработало для меня.

Пожалуйста, сначала поместите Route2 в WebApiConfig. Также добавьте HttpGet и HttpPost перед каждым методом и включите имя контроллера и имя метода в URL.

WebApiConfig =>

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

Контроллер =>

public class ValuesController : ApiController
{

    [HttpPost]
    public string GetCustomer([FromBody] RequestModel req)
    {
        return "Customer";
    }

    [HttpPost]
    public string GetCustomerList([FromBody] RequestModel req)
    {
        return "Customer List";
    }
}

URL =>

http://localhost:7050/api/Values/GetCustomer

http://localhost:7050/api/Values/GetCustomerList

Я обнаружил, что когда у меня есть два метода Get, один без параметров и один со сложным типом в качестве параметра, я получил ту же ошибку. Я решил эту проблему, добавив фиктивный параметр типа int с именем Id в качестве первого параметра, за которым последовал мой параметр сложного типа. Затем я добавил параметр сложного типа в шаблон маршрута. Следующее сработало для меня.

Сначала получите:

public IEnumerable<SearchItem> Get()
{
...
}

Второй получить:

public IEnumerable<SearchItem> Get(int id, [FromUri] List<string> layers)
{
...
}

WebApiConfig:

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

Это возможно благодаря использованию контроллера MVC вместо контроллера Web API. Проверьте пространство имен в контроллере Web API, оно должно быть следующим

using System.Net;
using System.Net.Http;
using System.Web.Http;

Если пространство имен следующее, то при вызове метода контроллера web api выдается ошибка выше.

using System.Web;
using System.Web.Mvc;

Можете добавить [Route("api/[controller]/[action]")] к вашему классу контроллера.

[Route("api/[controller]/[action]")]
[ApiController]
public class MySuperController : ControllerBase
{
 ...
}

Я наткнулся на эту проблему, пытаясь дополнить свои контроллеры WebAPI дополнительными действиями.

Предположим, вы бы

public IEnumerable<string> Get()
{
    return this.Repository.GetAll();
}

[HttpGet]
public void ReSeed()
{
    // Your custom action here
}

Теперь есть два метода, которые удовлетворяют запросу на /api/controller, который вызывает проблему, описанную TS.

Я не хотел добавлять "фиктивные" параметры в свои дополнительные действия, поэтому я посмотрел на действия по умолчанию и придумал:

[ActionName("builtin")]
public IEnumerable<string> Get()
{
    return this.Repository.GetAll();
}

для первого метода в сочетании с "двойной" привязкой маршрута:

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

config.Routes.MapHttpRoute(
    name: "CustomActionApi",
    routeTemplate: "api/{controller}/{action}");

Обратите внимание, что хотя в первом шаблоне маршрута нет параметра "action", очевидно, вы все равно можете настроить действие по умолчанию, позволяющее нам разделять маршрутизацию "обычных" вызовов WebAPI и вызовов на дополнительное действие.

Пожалуйста, убедитесь, что у вас есть два метода с разными именами и одинаковыми параметрами.

Если это так, пожалуйста, удалите любой из методов и попробуйте.

In my Case Everything was right

1) Web Config was configured properly 2) Route prefix and Route attributes were proper

Still i was getting the error. In my Case "Route" attribute (by pressing F12) was point to System.Web.MVc but not System.Web.Http which caused the issue.

Например => TestController

        [HttpGet]
        public string TestMethod(int arg0)
        {
            return "";
        }

        [HttpGet]
        public string TestMethod2(string arg0)
        {
            return "";
        }

        [HttpGet]
        public string TestMethod3(int arg0,string arg1)
        {
            return "";
        }

Если вы можете только изменить файл WebApiConfig.cs.

 config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/",
                defaults: null
            );

Это оно:)

И результат:

Вы пробовали:

[HttpGet("Summary")]
public HttpResponseMessage Summary(MyVm vm)
{
    return null;
}

[HttpGet("FullDetails")]
public HttpResponseMessage FullDetails()
{
    return null;
}

Убедитесь, что вы НЕ украшаете ваши методы контроллера для стандартных действий GET|PUT|POST|DELETE с атрибутом [HttpPost/Put/Get/Delete]. Я добавил этот атрибут к своему действию контроллера Vanilla Post, и он вызвал 404.

Надеюсь, что это поможет кому-то, так как это может быть очень неприятно и остановить прогресс.

Я знаю, что это старый вопрос, но иногда, когда вы используете сервисные ресурсы, такие как AngularJS, для подключения к WebAPI, убедитесь, что вы используете правильный маршрут, в противном случае возникает эта ошибка.

Другие вопросы по тегам