it-roy-ru.com

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

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

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

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

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

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

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

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

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].

424
Jed

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

55
Marc Stevenson

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

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

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

14
Filip W

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

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) 

12
Moatasem bakri

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

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

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

5
Joanna Derks

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

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

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

4
Max

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

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

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

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

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

2
Ramesh

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

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

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

using System.Web;
using System.Web.Mvc;
2
Ujwal Khairnar

Я наткнулся на эту проблему, пытаясь дополнить свои контроллеры 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 и вызовов на дополнительное действие.

2
Bjørn van Dommelen

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

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

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

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

0
Hemanth Vatti

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

0
Cemre Onur Baş

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

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

0
ComeIn

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

0
Suresh Kaushik

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

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

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