Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web API routing with multiple parameters

I'm trying to work out how to do the routing for the following Web API controller:

public class MyController : ApiController {     // POST api/MyController/GetAllRows/userName/tableName     [HttpPost]     public List<MyRows> GetAllRows(string userName, string tableName)     {         ...     }      // POST api/MyController/GetRowsOfType/userName/tableName/rowType     [HttpPost]     public List<MyRows> GetRowsOfType(string userName, string tableName, string rowType)     {         ...     } } 

At the moment, I'm using this routing for the URLs:

routes.MapHttpRoute("AllRows", "api/{controller}/{action}/{userName}/{tableName}",                     new                     {                         userName= UrlParameter.Optional,                         tableName = UrlParameter.Optional                     });  routes.MapHttpRoute("RowsByType", "api/{controller}/{action}/{userName}/{tableName}/{rowType}",                     new                     {                         userName= UrlParameter.Optional,                         tableName = UrlParameter.Optional,                         rowType= UrlParameter.Optional                     }); 

but only the first method (with 2 parameters) is working at the moment. Am I on the right lines, or have I got the URL format or routing completely wrong? Routing seems like black magic to me...

like image 547
Mourndark Avatar asked Jan 15 '14 14:01

Mourndark


People also ask

How do you pass multiple parameters in route attribute?

you could add a route like: routes. MapRoute( "ArtistImages", // Route name "{controller}/{action}/{artistName}/{apikey}", // URL with parameters new { controller = "Home", action = "Index", artistName = "", apikey = "" } // Parameter defaults );

How do I specify a route in Web API?

The default route template for Web API is "api/{controller}/{id}". In this template, "api" is a literal path segment, and {controller} and {id} are placeholder variables. When the Web API framework receives an HTTP request, it tries to match the URI against one of the route templates in the routing table.

Can we have multiple get methods in Web API?

As mentioned, Web API controller can include multiple Get methods with different parameters and types. Let's add following action methods in StudentController to demonstrate how Web API handles multiple HTTP GET requests.


1 Answers

I have seen the WebApiConfig get "out of control" with hundreds of routes placed in it.

Instead I personally prefer Attribute Routing

You are making it confusing with POST and GET

[HttpPost] public List<MyRows> GetAllRows(string userName, string tableName) {    ... } 

HttpPost AND GetAllRows ?

Why not instead do this:

[Route("GetAllRows/{user}/{table}")] public List<MyRows> GetAllRows(string userName, string tableName) {    ... } 

OR change to Route("PostAllRows" and PostRows I think that you are truly doing a GET request so the code I show should work for you. Your call from client would be WHATEVER is in the ROUTE , so it WILL FIND your METHOD with GetAllRows, but the method itself , that name CAN BE anything that you want, so as long as the caller matches the URL in ROUTE, you could put in GetMyStuff for the method if you really wanted to.

Update:

I actually prefer to be explicit with type of HTTP methods AND I prefer to match the route params to the method params

[HttpPost] [Route("api/lead/{vendorNumber}/{recordLocator}")] public IHttpActionResult GetLead(string vendorNumber, string recordLocator) { .... } 

(the route lead does not need to match method name GetLead but you will want to keep the same names on the route params and the method params, even though you can change the order e.g. put recordLocator before vendorNumber even if the route is the opposite - I don't do that , as why make it more confusing to look at).

Bonus: Now you can always use regex in routes as well, example

[Route("api/utilities/{vendorId:int}/{utilityType:regex(^(?i)(Gas)|(Electric)$)}/{accountType:regex(^(?i)(Residential)|(Business)$)}")] public IHttpActionResult GetUtilityList(int vendorId, string utilityType, string accountType)     { 
like image 115
Tom Stickel Avatar answered Sep 23 '22 02:09

Tom Stickel