Question

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?

Was it helpful?

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) { ... }

OTHER TIPS

Can you hard code those routes? If so, something similar to this should work.

config.Routes.MapHttpRoute(
    name: "CompanyByNameRoute",
    routeTemplate: "api/Search/CompanyByName/{name},
    defaults: new { controller = "Search", action = "CompanyByName", name = RouteParameter.Optional }
    );
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top