Search code examples
asp.net-mvc-4asp.net-web-apiasp.net-routingasp.net-web-api-routing

Routing string parameters in ASP.NET


As I've created a seperate search controller with multiple get methods, I needed to modify the default routes.

SearchController.cs

[HttpGet]
public IEnumerable<Object> CompanyByOrderId(long id) { ... }
[HttpGet]
public IEnumerable<Object> CompanyByName(string name) { ... }
[HttpGet]
public IEnumerable<Object> UserByName(string name) { ... }

WebApiConfig.cs

public static void Register(HttpConfiguration config)
{
    config.Routes.MapHttpRoute(
        name: "ActionById",
        routeTemplate: "api/Search/{action}/{id}",
        defaults: new { controller = "Search", id = RouteParameter.Optional }
     );

     config.Routes.MapHttpRoute(
         name: "ActionByName",
         routeTemplate: "api/Search/{action}/{name}",
         defaults: new { controller = "Search", name = RouteParameter.Optional }
      );

      config.Routes.MapHttpRoute(
          name: "DefaultApi",
          routeTemplate: "api/{controller}/{id}",
          defaults: new { id = RouteParameter.Optional }
      );
}

Referring to http://localhost:52498/api/Search/CompanyByOrderId/1 works fine. But calling one of the other methods with a name as parameter results in 404 error. E.g. http://localhost:52498/api/Search/UserByName/john

How do I specify that the URI with the string parameter is mapped to the CompanyByName / UserByName methods?


Solution

  • You could add a constraint to your first route so that it will only match numbers for the {id} parameter:

    config.Routes.MapHttpRoute(
        name: "ActionById",
        routeTemplate: "api/Search/{action}/{id}",
        defaults: new { controller = "Search", id = RouteParameter.Optional },
        constraints: new { id = @"\d+" }
    );
    

    Alternatively you could remove your second route entirely and change your action signatures to use only the {id} parameter:

    [HttpGet]
    public IEnumerable<Object> CompanyByOrderId(long id) { ... }
    [HttpGet]
    public IEnumerable<Object> CompanyByName(string id) { ... }
    [HttpGet]
    public IEnumerable<Object> UserByName(string id) { ... }