C# Web.API MapHttpRoute 参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14764177/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Web.API MapHttpRoute parameters
提问by Nicros
I'm having problems with my Web.API routing. I have the following two routes:
我的 Web.API 路由有问题。我有以下两条路线:
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.
这两个人似乎不能并肩生活。如果我在 WebApiConfig 中注释掉 MethodOne 路由,则 MethodTwo 路由有效。注释 MethodTwo 路线允许 MethodOne 工作。不加注释,MethodOne 有效,但 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.
我希望对这两个都使用一个路由,然后它们似乎必须具有相同的参数名称。谁编写带有泛型参数名称的方法?坏的。我真的不希望我的方法具有相同的参数名称(如 p1、p2、p3),所以我想我可以为新方法创建一个路由。但即使这样似乎也行不通。
I really miss the WebGet(UriTemplate="")
from WCF rest.
我真的很想念WebGet(UriTemplate="")
来自 WCF 的休息。
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.
我有一个控制器,它有很多方法,有些方法有 1、2、3 甚至更多的参数。我不敢相信我不能在 MapHttpRoute 方法中使用有意义的参数名称。
I could comment that stuff out entirely and use WebGet()
… but before I got there I wanted to see if I'm missing something.
我可以完全注释掉这些东西并使用WebGet()
……但在我到达那里之前,我想看看我是否遗漏了什么。
采纳答案by Hongmei Ge
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.
您看到此问题的原因是您的第一个路由将匹配两个请求。URL 中的 id 和 type 标记将匹配两个请求,因为在运行路由时,它将尝试解析 URL 并将每个段与您的 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.
即使您使用 WebGet,您也可能需要做一些类似的事情来消除我认为的这两种方法的歧义。
回答by Youssef Moussaoui
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:
您可以选择在查询字符串中传递参数,如 /MethodTwo?directory=a&report=b,但如果您希望它们显示在路径中,这看起来是基于属性的路由的不错选择。Filip 在这里发表了一篇很棒的文章:
http://www.strathweb.com/2012/05/attribute-based-routing-in-asp-net-web-api/
http://www.strathweb.com/2012/05/attribute-based-routing-in-asp-net-web-api/
回答by nick66
From http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection
来自http://www.asp.net/web-api/overview/web-api-routing-and-actions/routing-and-action-selection
You can also provide constraints, which restrict how a URI segment can match a placeholder:
constraints: new { id = @"\d+" } // Only matches if "id" is one or more digits.
您还可以提供约束,以限制 URI 段如何匹配占位符:
约束: new { id = @"\d+" } // 仅当“id”是一位或多位数字时才匹配。
Adding this constraint to "MethodOne" (api/{controller}/{action}/{id}/{type}) would mean that numbers it only matches if {id} is a number otherwise it would match "MethodTwo" ("api/{controller}/{action}/{directory}/{report}").
将此约束添加到“MethodOne”(api/{controller}/{action}/{id}/{type}) 将意味着它仅在 {id} 是数字时才匹配数字,否则它将匹配“MethodTwo”(“api /{controller}/{action}/{directory}/{report}”)。