Web Api routing limitations?

Royi Namir

Say I have this 2 actions in my Api Controller :

    [HttpGet]
    public Product ProductById(int id)
    {
      ...
        return item;
    }

    [HttpGet]
    public string ProductByString(string st)
    {
        return "String Result";
    }

I also have these 2 routes :

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

  config.Routes.MapHttpRoute("DefaultApi2", "api/{controller}/{st}");

Running http://mysite:9000/api/products/1 will work.

It will catch the first route because there's a match.

if I wanted the STRING action version I must do :

http://mysite:9000/api/products/?st=blabla this will be using ALSO the first route. ( query string is not negotiation to match a route).

If I swap the routes , only the DefaultApi2 route is hit. ( I do understand why it is happening).

So my conclusion is that I will never be able to do both:

http://mysite:9000/api/products/1

And

http://mysite:9000/api/products/Guitar

In other words - the second route will never be a match.

Question

Besides

  • mentioning the {action} name in the route (not recommended ,web Api conventions)
  • using route attribute ( I dont use webApi 2)

What is the right way of solving this issue ? I can see how it can be complicated ( I 'll have to remember : only the int ID has the x/y/id thing , for others I must use querystring etc etc.... I can get lost easily - in a big application)

Patrick Hofman

I guess it can be fixed with three routes:

config.Routes.MapHttpRoute("DefaultApi",
               "api/{controller}/{id}",
               contraint: new { id = @"\d+" }
               );
// only matches numeric id's

config.Routes.MapHttpRoute("DefaultApi2", "api/{controller}/{st}");
// only matches having a parameter, no matter what data type

config.Routes.MapHttpRoute("DefaultApi3",
               "api/{controller}/{id}",
               new
               {
                       id = RouteParameter.Optional
               });
// matches the empty id

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related