3

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.

7
  • It should not match first route. That route has a constraint that only allows numbers new { id = @"\d+" } for id parameter. And that is so that it wont clash with the second route mapping Commented Feb 10, 2017 at 16:50
  • I think for your first GET, you have specified a mask here: new { id = @"\d+" }, try removing it. But also i think you should have only one method with a simple decision: if ID is passed then return an Object, else return a list. But I'd take another way. Commented Feb 10, 2017 at 16:50
  • If i remove the constraint i get an error "Multiple actions were found that match the request: \r\nSystem.Net.Http.HttpResponseMessage Get() ". This makes sense as i have 2 get methods. One that takes an id and another that takes none in order to return a list of records Commented Feb 10, 2017 at 16:53
  • @DanHastings, two routes now conflict with each other if you remove the constraint Commented Feb 10, 2017 at 16:54
  • 1
    @DanHastings - It is unclear what your exact question is. Why would you expect the first route to match, when you specifically constrained it so it won't match when you pass a non-digit? What do you expect as a result when you pass a controller name that doesn't match if not the error message you are getting? Commented Feb 10, 2017 at 17:20

1 Answer 1

2

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 }
);
Sign up to request clarification or add additional context in comments.

2 Comments

This resolves the issue, but in turn it creates the same issue i had before. Multiple actions were found that match the request: \r\nSystem.Net.Http.HttpResponseMessage Get() on type. I want one controller to work like this /controller/ = call get(), /controller/id = call get(string id)
Bingo, this does the job. Dunno why, but I thought that hardcoding the action to get would cause issues but this seems to have worked perfectly

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.