Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web.API MapHttpRoute parameters

Tags:

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.

like image 251
Nicros Avatar asked Feb 08 '13 01:02

Nicros


People also ask

How do I set optional parameters in Web API?

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.

How does Web API define routing?

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.


2 Answers

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/

like image 30
Youssef Moussaoui Avatar answered Sep 30 '22 23:09

Youssef Moussaoui


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.

like image 165
Hongmei Ge Avatar answered Sep 30 '22 21:09

Hongmei Ge