I have a simple query on ASP.Net Web API Routing. I have the following controller:
public class CustomersController: ApiController
{
public List<SomeClass> Get(string searchTerm)
{
if(String.IsNullOrEmpty(searchTerm))
{
//return complete List
}
else
{
//return list.where (Customer name contains searchTerm)
}
}
}
My routing configuration (Conventional) looks like this:
config.Routes.MapHttpRoute(name:"DefaultApi",
routeTemplate:"api/{controller}/{id}"
defaults:new {id = RouteParameter.Optional});
config.Routes.MapHttpRoute(name:"CustomersApi",
routeTemplate:"api/{controller}/{searchTerm}"
defaults:new {searchTerm = RouteParameter.Optional});
If I hit the url: http://localhost:57169/api/Customers/Vi I get a 404-Not found
If I reverse the order of the routes, it works. So the question is in the first case, is it matching the first route (DefaultApi)? If not, why is it not trying the second route?
This route template
config.Routes.MapHttpRoute(name:"DefaultApi",
routeTemplate:"api/{controller}/{id}",
defaults:new {id = RouteParameter.Optional}
);
match your URL because Id
can be any type : string
, int
etc. So your URL respect this template and this route is chosen.
To make this template more restrcitive and make ASP.Net Web API to go to the next template you need to add to it some constraints by saying something like "Id
parameter must be a numeric type for this template". So you add constraints
parameter like below:
config.Routes.MapHttpRoute(name:"DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new {id = RouteParameter.Required}, // <- also here I put Required to make sure that when your user doesn't give searchTerm so this template will not be chosen.
constraints: new {id = @"\d+"} // <- regular expression is used to say that id must be numeric value for this template.
);
So by using this URL http://localhost:57169/api/Customers/Vi the above template will be skipped and the next will be chosen.