route net mvc attribute asp asp.net routing controller asp.net-web-api action

asp.net - net - Enrutamiento de API web-api/{controller}/{action}/{id} "dysfunctions" api/{controller}/{id}



web api 2 route config (2)

Tengo la ruta predeterminada en Global.asax:

RouteTable.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = System.Web.Http.RouteParameter.Optional } );

Quería poder orientarme a una función específica, así que creé otra ruta:

RouteTable.Routes.MapHttpRoute( name: "WithActionApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = System.Web.Http.RouteParameter.Optional } );

Entonces, en mi controlador, tengo:

public string Get(int id) { return "object of id id"; } [HttpGet] public IEnumerable<string> ByCategoryId(int id) { return new string[] { "byCategory1", "byCategory2" }; }

Llamar a .../api/records/bycategoryid/5 me dará lo que quiero. Sin embargo, llamar .../api/records/1 me dará el error

Se encontraron varias acciones que coinciden con la solicitud: ...

Entiendo por qué: las rutas solo definen qué URL son válidas, pero cuando se trata de la función, tanto Get(int id) como ByCategoryId(int id) coinciden con api/{controller}/{id} , que es lo que confunde el marco.

¿Qué debo hacer para que funcione la ruta predeterminada de la API y conservar la que tiene {action} ? Pensé en crear un controlador diferente llamado RecordByCategoryIdController para que coincida con la ruta API predeterminada, para lo cual solicitaría .../api/recordbycategoryid/5 . Sin embargo, considero que es una solución "sucia" (por lo tanto, insatisfactoria). He buscado respuestas sobre esto y ningún tutorial sobre el uso de una ruta con {action} incluso menciona este problema.


El motor de ruta usa la misma secuencia en la que agrega reglas. Una vez que obtiene la primera regla coincidente, dejará de verificar otras reglas y tomará esto para buscar controlador y acción.

Entonces, debes:

  1. Ponga sus reglas específicas por delante de sus reglas generales (como por defecto), lo que significa utilizar RouteTable.Routes.MapHttpRoute para asignar primero "WithActionApi", luego "DefaultApi".

  2. Elimine los defaults: new { id = System.Web.Http.RouteParameter.Optional } parámetro defaults: new { id = System.Web.Http.RouteParameter.Optional } de su regla "WithActionApi" porque una vez que la identificación es opcional, la URL como "/ api / {part1} / {part2}" nunca entrará en " DefaultApi ".

  3. Agregue una acción nombrada a su "DefaultApi" para indicarle al motor de la ruta qué acción debe ingresar. De lo contrario, una vez que tenga más de una acción en su controlador, el motor no sabrá cuál usar y arrojará "Se encontraron varias acciones que coinciden con la solicitud: ...". Luego, para hacer que coincida con su método Get, use ActionNameAttribute .

Entonces su ruta debería tener esto:

// 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 } );

Y tu controlador:

[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" }; }


Puede resolver su problema con la ayuda del enrutamiento de atributos

Controlador

[Route("api/category/{categoryId}")] public IEnumerable<Order> GetCategoryId(int categoryId) { ... }

URI en jquery

api/category/1

Configuración de ruta

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

y su enrutamiento predeterminado funciona como enrutamiento predeterminado basado en convenciones

Controlador

public string Get(int id) { return "object of id id"; }

URI en Jquery

/api/records/1

Configuración de ruta

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 } ); } }

Revise el artículo para más información Enrutamiento de atributos y enrutamiento basado en convenciones aquí y this