Web API Routing-api / {controller} / {action} / {id}" дисфункции " api / {controller} / {id}
у меня есть маршрут по умолчанию в 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" правило, потому что как только id является необязательным, 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.
}
}
}
и ваша маршрутизация по умолчанию работает как default маршрутизация на основе соглашения
контроллер
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 }
);
}
}