tutorial net iactionresult example asp apicontroller asp.net-web-api

asp.net-web-api - net - web api rest c#



Sobrecarga el método de acción web api en función del tipo de parámetro (2)

¿Hay alguna forma de realizar una sobrecarga basada en el tipo de parámetro de un método de Acción? es decir, ¿es posible hacer lo siguiente en un controlador?

public class MyController : ApiController { public Foo Get(int id) { //whatever } public Foo Get(string id) { //whatever } public Foo Get(Guid id) { //whatever } }

Si es así, qué cambios se deben realizar en la tabla de rutas.


Este tipo de escenario no está bien soportado por los métodos de enrutamiento estándar.

Es posible que desee utilizar el enrutamiento basado en atributos, ya que esto le da mucha más flexibilidad.

Mire específicamente las restricciones de ruta donde puede enrutar por tipo:

// Type constraints [GET("Int/{x:int}")] [GET("Guid/{x:guid}")]

Cualquier otra cosa se convertirá en un truco ... por ejemplo

Si lo intentó usando el enrutamiento estándar, probablemente necesite enrutar a la acción correcta a través de su nombre, luego use las restricciones del registro (por ejemplo, guid ) para enrutar a la acción predeterminada requerida.

Controladores:

public class MyController : ApiController { [ActionName("GetById")] public Foo Get(int id) { //whatever } [ActionName("GetByString")] public Foo Get(string id) { //whatever } [ActionName("GetByGUID")] public Foo Get(Guid id) { //whatever } }

Rutas:

//Should match /api/My/1 config.Routes.MapHttpRoute( name: "DefaultDigitApi", routeTemplate: "api/{controller}/{id}", defaults: new { action = "GetById" }, constraints: new { id = @"^/d+$" } // id must be digits ); //Should match /api/My/3ead6bea-4a0a-42ae-a009-853e2243cfa3 config.Routes.MapHttpRoute( name: "DefaultGuidApi", routeTemplate: "api/{controller}/{id}", defaults: new { action = "GetByGUID" }, constraints: new { id = @"^(/{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}/}{0,1})$" } // id must be guid ); //Should match /api/My/everything else config.Routes.MapHttpRoute( name: "DefaultStringApi", routeTemplate: "api/{controller}/{id}", defaults: new { action = "GetByString" } );

Actualizado

Normalmente usaría un POST si hago un FromBody (tal vez use el FromUri con el modelo) pero sus requisitos podrían cumplirse agregando lo siguiente.

Para el controlador

[ActionName("GetAll")] public string Get([FromBody]MyFooSearch model) { if (model != null) { //search criteria at api/my } //default for api/my } //should match /api/my config.Routes.MapHttpRoute( name: "DefaultCollection", routeTemplate: "api/{controller}", defaults: new { action = "GetAll" } );


Puede codificar sus métodos de la siguiente manera

[Route("api/My/{id:int}")] public string Get(int id) { return "value"; } [Route("api/My/{name:alpha}")] public string Get(string name) { return name; } [Route("api/My/{id:Guid}")] public string Get(Guid id) { return "value"; }