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

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

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

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

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

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

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

Ответ 1

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

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

Update:

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

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

Например, ваши два метода можно было бы преобразовать в:

public HttpResponseMessage Get()
{
    return null;
}

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

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

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

Ответ 2

Обновление с веб-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 - это имя вашего контроллера (без "контроллера" ). Это позволит вам получить каждое действие с указанным выше маршрутом.

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

Ответ 3

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

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

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

Ответ 4

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

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)

Ответ 6

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

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

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

Ответ 7

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

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

Ответ 8

Я обнаружил, что когда у меня есть два метода 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 }
);

Ответ 9

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

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

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

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

Ответ 10

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

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

Ответ 11

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

Предположим, что у вас есть

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

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

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

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

[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 и вызовов дополнительного действия.

Ответ 12

Это ответ для всех, кто знает, что все правильно и проверил 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 часов.

Ответ 13

В моем случае все было правильно

1) Web Config был настроен правильно 2) Префикс маршрута и атрибуты маршрута были правильными

Тем не менее я получаю ошибку. В моем случае атрибут "Маршрут" (нажатием клавиши F12) указывал на System.Web.MVc, но не на System.Web.Http, который вызвал проблему.

Ответ 14

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

Ответ 15

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

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

Ответ 16

Например => 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
            );

Это оно :)

И результат: enter image description here

Ответ 17

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

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

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

Ответ 18

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

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