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

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

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

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

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

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

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

13 ответов


ваша карта маршрута, вероятно, что-то вроде этого:

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

обновление:

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

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

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

public HttpResponseMessage Get()
{
    return null;
}

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

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

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


обновление с Web 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


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

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

вам нужно различать их по параметру querystring или route чтобы устранить двусмысленность.


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

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)


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

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

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


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

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

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


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

сначала сделать:

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

второй 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 }
);

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

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


я наткнулся на эту проблему, пытаясь увеличить мои контроллеры 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}");

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


это возможно из-за использования контроллера 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;

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

пожалуйста, поместите 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

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


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

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