Search code examples
c#asp.net-web-apiasp.net-web-api-routing

Basic Conventional routing asp.net webapi


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?


Solution

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