我正在为Web API 2应用程序使用System.Web.Http.RouteAttribute并System.Web.Http.RoutePrefixAttribute启用更干净的URL。对于我的大多数请求,我可以使用路由(例如Controller/param1/param2)或查询字符串(例如Controller?param1=bob¶m2=mary)。
System.Web.Http.RouteAttribute
System.Web.Http.RoutePrefixAttribute
Controller/param1/param2
Controller?param1=bob¶m2=mary
不幸的是,对于我的一个控制器(只有一个),这失败了。这是我的控制器:
[RoutePrefix("1/Names")] public class NamesController : ApiController { [HttpGet] [Route("{name}/{sport}/{drink}")] public List<int> Get(string name, string sport, string drink) { // Code removed... } [HttpGet] [Route("{name}/{drink}")] public List<int> Get(string name, string drink) { // Code removed... } }
当我请求使用路由时,两者都可以正常工作。但是,如果我使用查询字符串,它将失败,并告诉我该路径不存在。
我尝试将以下内容添加到我的WebApiConfig.cs类的Register(HttpConfiguration config)函数中(“默认”路由之前和之后),但是它什么也没做:
WebApiConfig.cs
Register(HttpConfiguration config)
config.Routes.MapHttpRoute( name: "NameRoute", routeTemplate: "{verId}/Names/{name}/{sport}/{drink}", defaults: new { name = RouteParameter.Optional, sport = RouteParameter.Optional, drink = RouteParameter.Optional }, constraints: new { verId = @"\d+" });
为了清楚起见,我希望能够做到这两个:
localhost:12345/1/Names/Ted/rugby/coke localhost:12345/1/Names/Ted/coke
和,
localhost:12345/1/Names?name=Ted&sport=rugby&drink=coke localhost:12345/1/Names?name=Ted&drink=coke
但遗憾的是查询字符串版本不起作用!:(
更新
我完全删除了第二个Action,现在尝试仅使用带有可选参数的单个Action。我已将路线属性更改[Route("{name}/{drink}/{sport?}")]为Tony建议将运动设置为可空,但是localhost:12345/1/Names/Ted/coke由于某些原因,这现在已成为无效路线。查询字符串的行为与以前相同。
[Route("{name}/{drink}/{sport?}")]
localhost:12345/1/Names/Ted/coke
更新2 我现在在控制器中有一个单独的动作:
[RoutePrefix("1/Names")] public class NamesController : ApiController { [HttpGet] [Route("{name}/{drink}/{sport?}")] public List<int> Get(string name, string drink, string sport = "") { // Code removed... } }
但是使用查询字符串却找不到合适的路径,而使用路由方法却找到合适的路径。
经过艰苦的摆弄和谷歌搜索之后,我想出了一个“解决方案”。我不知道这是否是理想/最佳实践/陈旧的错误,但这可以解决我的问题。
[Route("")]除了已经使用的路由属性外,我所做的只是添加。基本上,这使Web API 2路由允许查询字符串,因为它现在是有效的路由。
[Route("")]
现在的示例是:
[HttpGet] [Route("")] [Route("{name}/{drink}/{sport?}")] public List<int> Get(string name, string drink, string sport = "") { // Code removed... }
这既使localhost:12345/1/Names/Ted/coke又localhost:12345/1/Names?name=Ted&drink=coke有效。
localhost:12345/1/Names?name=Ted&drink=coke