Search code examples
c#asp.netasp.net-mvcasp.net-mvc-4asp.net-mvc-routing

Allow string ID with ASP.NET MVC route


I have the 2 following routes setup and they are working fine when a valid request is sent.

config.Routes.MapHttpRoute("DefaultApiWithId", "{controller}/{id}", new { id = RouteParameter.Optional }, new { id = @"\d+" });
config.Routes.MapHttpRoute("DefaultApiWithAction", "{controller}/{action}");

I wanted to test some bad request to make sure the response was correct. I am trying to call the following Action in my controller.

public HttpResponseMessage Get(string id)
{
    //output the id again
}

If i call localhost:80/users/123, i get a response back that is valid and it will output 123. When i try to use an invalid ID, for example, one that contains letters it fails with the following error.

{"Message":"No HTTP resource was found that matches the request URI 'http://localhost:80/users/d1g'.","MessageDetail":"No action was found on the controller 'Users' that matches the name 'd1g'."}

I can see whats going wrong. This request should be matching the first route, but instead its matching the second route. I have 2 methods called Get. One accepts an ID and the other doesn't require an ID. The one that does not require an ID returns a list of all records. I was having a lot of trouble with this and the route above is how i solved the issue.


Solution

  • Update the routes by removing constraint, updating route with action to avoid conflict and then switching the order.

    config.Routes.MapHttpRoute(
        "DefaultApiWithAction", 
        "{controller}/{action}/{id}"
        new { id = RouteParameter.Optional }
    );
    
    config.Routes.MapHttpRoute(
        "DefaultApiWithId", 
        "{controller}/{id}", 
        new { action = "Get", id = RouteParameter.Optional }
    );