I'm having problems with my Web.API routing. I have the following two routes:
config.Routes.MapHttpRoute(
name: "MethodOne",
routeTemplate: "api/{controller}/{action}/{id}/{type}",
defaults: new { id = RouteParameter.Optional, type = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "MethodTwo",
routeTemplate: "api/{controller}/{action}/{directory}/{report}",
defaults: new { directory = RouteParameter.Optional, report = RouteParameter.Optional }
);
And in my controller these two methods:
[HttpGet]
[ActionName("methodone")]
public string MethodOne(string id, string type)
{
return string.Empty;
}
[HttpGet]
[ActionName("methodtwo")]
public string MethodTwo(string directory, string report)
{
return string.Empty;
}
These two seemingly cannot live side by side. If I comment out the MethodOne route in WebApiConfig, the MethodTwo route works. Commenting MethodTwo route allows MethodOne to work. Leaving both uncommented, MethodOne works, but not MethodTwo.
I was hoping to use one route for both of these then it seems they would have to have the same parameter names. Who writes methods with generic parameter names? Bad. I really don't want my methods to have the same parameter names (like p1, p2, p3), so I thought I could create a route just for the new method. But even this doesn't seem to work.
I really miss the WebGet(UriTemplate="")
from WCF rest.
I have one controller that has many methods, some with 1, 2, 3 or even more parameters. I can't believe I cant use meaningful parameter names with the MapHttpRoute approach.
I could comment that stuff out entirely and use WebGet()
… but before I got there I wanted to see if I'm missing something.
Optional Parameters in Web API Attribute Routing and Default Values: You can make a URI parameter as optional by adding a question mark (“?”) to the route parameter. If you make a route parameter as optional then you must specify a default value by using parameter = value for the method parameter.
Routing is how Web API matches a URI to an action. Web API 2 supports a new type of routing, called attribute routing. As the name implies, attribute routing uses attributes to define routes. Attribute routing gives you more control over the URIs in your web API.
You can choose to pass the parameters in the query string like /MethodTwo?directory=a&report=b, but if you'd rather they show up in the path, this looks like a good candidate for attribute-based routing. Filip has a great post about it here:
http://www.strathweb.com/2012/05/attribute-based-routing-in-asp-net-web-api/
The reason you are seeing this problem is because your first route will match both requests. The id and type token in the URL will match both requests because when the route is being run, it will try parse the URL and match each segment against your URL.
So your first route will happily match both requests as follows.
~/methodone/1/mytype => action = methodone, id = 1, and type = mytype
~/methodtwo/directory/report => action = methodtwo, id = directory, and type = report
To work around this, you should use route like
config.Routes.MapHttpRoute(
name: "MethodOne",
routeTemplate: "api/{controller}/methodone/{id}/{type}",
defaults: new { id = RouteParameter.Optional, type = RouteParameter.Optional }
);
config.Routes.MapHttpRoute(
name: "MethodTwo",
routeTemplate: "api/{controller}/methodtwo/{directory}/{report}",
defaults: new { directory = RouteParameter.Optional, report = RouteParameter.Optional }
);
Even if you use WebGet, you might need to do something similarly to disambiguous those two methods I believe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With