Mam domyślną trasę w Global.asax:
RouteTable.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
Chciałem mieć możliwość kierowania na określoną funkcję, więc stworzyłem inną trasę:
RouteTable.Routes.MapHttpRoute(
name: "WithActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = System.Web.Http.RouteParameter.Optional }
);
Tak więc w moim kontrolerze mam:
public string Get(int id)
{
return "object of id id";
}
[HttpGet]
public IEnumerable<string> ByCategoryId(int id)
{
return new string[] { "byCategory1", "byCategory2" };
}
Dzwonienie .../api/records/bycategoryid/5
da mi to, czego chcę. Jednak dzwonienie .../api/records/1
da mi błąd
Znaleziono wiele działań pasujących do żądania: ...
Rozumiem, dlaczego tak jest - trasy po prostu definiują, które adresy URL są prawidłowe, ale jeśli chodzi o dopasowywanie funkcji, zarówno, jak Get(int id)
i ByCategoryId(int id)
dopasuj api/{controller}/{id}
, co myli strukturę.
Co muszę zrobić, aby domyślna trasa interfejsu API znów działała i zachować tę z {action}
? Pomyślałem o stworzeniu innego kontrolera o nazwie RecordByCategoryIdController
pasującej do domyślnej trasy API, o którą chciałbym poprosić .../api/recordbycategoryid/5
. Uważam jednak, że jest to „brudne” (a więc niezadowalające) rozwiązanie. Szukałem odpowiedzi na ten temat i nie ma tam samouczka na temat korzystania z trasy, {action}
nawet jeśli wspomina o tym problemie.
źródło
id
jest opcjonalne, wówczas adres URL/api/{part1}/{part2}
może nadal przejść doDefaultApi
trasy, jeśli nie zostanie znalezione pasujące działanie dlaWithActionApi
trasy. Proszę popraw mnie jeżeli się mylę.Możesz rozwiązać swój problem za pomocą routingu atrybutów
Kontroler
[Route("api/category/{categoryId}")] public IEnumerable<Order> GetCategoryId(int categoryId) { ... }
URI w jquery
Konfiguracja trasy
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. } } }
a Twój domyślny routing działa jako domyślny routing oparty na konwencji
Kontroler
public string Get(int id) { return "object of id id"; }
URI w Jquery
Konfiguracja trasy
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 } ); } }
Przejrzyj artykuł, aby uzyskać więcej informacji o routingu atrybutów i routingu opartym na konwencji, tutaj i to
źródło
Spróbuj tego.
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 } ); } }
źródło
Możliwym powodem może być również to, że nie odziedziczyłeś kontrolera po ApiController. Zdarzyło mi się trochę czasu, zanim zrozumiałem to samo.
źródło
Aby rozróżnić trasy, spróbuj dodać ograniczenie, że identyfikator musi być numeryczny:
RouteTable.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", constraints: new { id = @"\d+" }, // Only matches if "id" is one or more digits. defaults: new { id = System.Web.Http.RouteParameter.Optional } );
źródło