Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overload web api action method based on parameter type

Is there a way to perform parameter type based overloading of an Action method ? i.e. Is it possible to do the following in a Controller

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

If so, what changes need to be made to the Route table.

like image 381
Abhijeet Patel Avatar asked Jan 16 '13 07:01

Abhijeet Patel


People also ask

Can you overload the Web API action method How?

Method overloading can be done in a web service with the following things: By changing the number of parameters used. By changing the order of parameters. By using different data types for the parameters.

Can action method be overloaded?

If we have to overload the action Method in asp.net MVC then we can not do it directly. We have to change the ActionName like this code snippet. Now to run the controller GetEmpName action method with just give the URL like this: http://localhost:49389/Home/GetEmpName.

Can you overload an API?

Overloading methods is a strong concept in API design, especially when your API is a fluent API or DSL (Domain Specific Language). This is the case for jOOQ, where you often want to use the exact same method name for various means of interaction with the library.

Can we overload method in Web service?

This is a very common interview question as well: Is it possible to overload a web method in a web service? The answer is yes, you need to use MessageName property for this.


Video Answer


1 Answers

This kind of scenario is not well supported by the standard routing methods.

You may want to use attribute based routing instead as this gives you a lot more flexibility.

Specifically look at the route constraints where you can route by the type:

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

Anything else will turn into a bit of a hack... e.g.

If you did attempt it using standard routing you would probably need to route to the correct action via it's name, then use reg ex's constraints (e.g. guid) to route to the required default action.

Controllers:

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

Routes:

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

Updated

I would normally use a POST if doing a FromBody (perhaps use the FromUri with the model instead) but your requirements could be met by adding the following.

For the controller

    [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" }             ); 
like image 111
Mark Jones Avatar answered Sep 20 '22 02:09

Mark Jones