Маршрутизации веб - АПИ-АПИ/{контроллера}/{действие}/{ИД} "дисфункции" по API/{контроллера}/{ИД}
у меня есть маршрут по умолчанию в Global.асакс:
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
я хотел иметь возможность ориентироваться на определенную функцию, поэтому я создал другой маршрут:
RouteTable.Routes.MapHttpRoute(
name: "WithActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
Итак, в моем контроллере, у меня есть:
public string Get(int id)
{
return "object of id id";
}
[HttpGet]
public IEnumerable<string> ByCategoryId(int id)
{
return new string[] { "byCategory1", "byCategory2" };
}
вызов .../api/records/bycategoryid/5
даст мне то, чего я хочу.
Однако, вызов .../api/records/1
даст мне ошибку
найдено несколько действий, которые соответствуют запросу: ...
я понимаю, почему это - маршруты просто определите, какие URL-адреса действительны, но когда дело доходит до сопоставления функций, оба Get(int id)
и ByCategoryId(int id)
матч api/{controller}/{id}
, что смущает рамках.
что мне нужно сделать, чтобы снова запустить маршрут API по умолчанию и сохранить его с {action}
? Я думал о создании другого контроллера с именем RecordByCategoryIdController
чтобы соответствовать маршруту API по умолчанию, для которого я бы запросил .../api/recordbycategoryid/5
. Однако я считаю, что это" грязное " (таким образом, неудовлетворительное) решение. Я посмотрел для ответов на этот и никакой учебник там по использованию маршрута с {action}
даже не упоминает эту проблему.
3 ответа:
механизм маршрута использует ту же последовательность, что и при добавлении в него правил. Как только он получит первое согласованное правило, он перестанет проверять другие правила и примет это для поиска контроллера и действия.
Итак, вы должны:
поставьте свои конкретные правила перед вашими общими правилами(например, по умолчанию), что означает использование
RouteTable.Routes.MapHttpRoute
для отображения "WithActionApi" сначала, затем "DefaultApi".удалить
defaults: new { id = System.Web.Http.RouteParameter.Optional }
параметр вашего " WithActionApi" правило, потому что после того, как идентификатор является необязательным, url-адрес типа "/api/{part1}/{part2}" никогда не переходит в "DefaultApi".добавьте именованное действие в свой" DefaultApi", чтобы сообщить движку маршрута, какое действие ввести. В противном случае, если у вас есть более одного действия в контроллере, движок не будет знать, какой из них использовать и бросает "было найдено несколько действий, которые соответствуют запросу: ...". Затем, чтобы он соответствовал вашему методу Get, используйте ActionNameAttribute.
так что ваш маршрут должен выглядеть так:
// Map this rule first RouteTable.Routes.MapRoute( "WithActionApi", "api/{controller}/{action}/{id}" ); RouteTable.Routes.MapRoute( "DefaultApi", "api/{controller}/{id}", new { action="DefaultAction", id = System.Web.Http.RouteParameter.Optional } );
и ваш контроллер:
[ActionName("DefaultAction")] //Map Action and you can name your method with any text public string Get(int id) { return "object of id id"; } [HttpGet] public IEnumerable<string> ByCategoryId(int id) { return new string[] { "byCategory1", "byCategory2" }; }
вы можете решить вашу проблему с помощью маршрут
контроллер
[Route("api/category/{categoryId}")] public IEnumerable<Order> GetCategoryId(int categoryId) { ... }
URI в jquery
api/category/1
Настройки Маршруту
using System.Web.Http; namespace WebApplication { public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API routes config.MapHttpAttributeRoutes(); // Other Web API configuration not shown. } } }
и ваш маршрут по умолчанию работает по умолчанию маршрутизация на основе соглашения
контроллер
public string Get(int id) { return "object of id id"; }
URI в Jquery
/api/records/1
Настройки Маршруту
public static class WebApiConfig { public static void Register(HttpConfiguration config) { // Attribute routing. config.MapHttpAttributeRoutes(); // Convention-based routing. config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); } }
обзор статьи для получения дополнительной информации маршрутизация атрибутов и маршрутизация на основе onvention здесь & этой
попробуйте это.
public class WebApiConfig { public static void Register(HttpConfiguration config) { // Web API configuration and services var json = config.Formatters.JsonFormatter; json.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("application/json")); config.Formatters.Remove(config.Formatters.XmlFormatter); // Web API routes config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional , Action =RouteParameter.Optional } ); } }