3

I have this:

[HttpGet]
[Route("Cats")]
public IHttpActionResult GetByCatId(int catId)

[HttpGet]
[Route("Cats")]
public IHttpActionResult GetByName(string name)

They are called by providing the query string eg Cats?catId=5

However MVC Web API will say you can't have multiple routes that are the same (both routes are "Cats".

How can I get this to work so MVC Web API will recognize them as separate routes? Is there something I can put into the Route property? It says that ? is an invalid character to put into a route.

1

2 Answers 2

4

You can merge the two actions in question into one

[HttpGet]
[Route("Cats")]
public IHttpActionResult GetCats(int? catId = null, string name = null) {

    if(catId.HasValue) return GetByCatId(catId.Value);

    if(!string.IsNullOrEmpty(name)) return GetByName(name);

    return GetAllCats();
}

private IHttpActionResult GetAllCats() { ... }

private IHttpActionResult GetByCatId(int catId) { ... }    

private IHttpActionResult GetByName(string name) { ... }

Or for more flexibility try route constraints

Referencing Attribute Routing in ASP.NET Web API 2 : Route Constraints

Route Constraints

Route constraints let you restrict how the parameters in the route template are matched. The general syntax is "{parameter:constraint}". For example:

[Route("users/{id:int}"]
public User GetUserById(int id) { ... }

[Route("users/{name}"]
public User GetUserByName(string name) { ... }

Here, the first route will only be selected if the "id" segment of the URI is an integer. Otherwise, the second route will be chosen.

Sign up to request clarification or add additional context in comments.

8 Comments

This method means users/5 works but not /users?name=5 which is what I need
In that case you would have to merge those two methods into one and perform the action based on the populated parameter.
otherwise you need to differentiate the two actions more so that there is not a conflict in route mapping
@NibblyPig, check updated answer and see if that works for you
Have tried this, it doesn't distinguish between names so if you have two routes, one takes string catId and one takes string catName you get an error Multiple actions were found that match the request if you go to theUrl?catId=CAT75 or `theUrl?catName=Jeff. If I use a single route with both parameters it doesn't work nicely with swagger/swashbuckle or other stuff like logging :(
|
4

Try applying constraints on attribute routing.

[HttpGet]
[Route("Cats/{catId:int}")]
public IHttpActionResult GetByCatId(int catId)

[HttpGet]
[Route("Cats/{name}")]
public IHttpActionResult GetByName(string name)

1 Comment

it is string by default. no need to put it just put {name}

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.