Найдено несколько действий, соответствующих запросу в 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
таким образом, вам может потребоваться добавить имя метода в таблицу маршрутизации.
без использования действий параметры будут:
переместите один из методов на другой контроллер, чтобы они не конфликтовали.
используйте только один метод, который принимает 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.
надеюсь, что это поможет кому-то, так как это может быть очень неприятно и остановить прогресс.