我使用WebAPI 2.2,基于属性的路由,我似乎无法弄清楚为什么查询字符串不起作用或如何启用它们。我已经阅读了其他有关这方面的问题,但它们并不适用于我。
这是一个非常简单的APIController:
[Route("api/HelloMessage")]
public async Task<IHttpActionResult> Get()
{
var result = await Task.FromResult(new string[] { "Hello", "World" }).ConfigureAwait(false);
return Ok(result);
}
[Route("api/HelloMessage/{id}")]
public async Task<IHttpActionResult> Get(int id)
{
var result = await Task.FromResult($"Hello {id}").ConfigureAwait(false);
return Ok(result);
}
(另外,转到WebApiConfig.cs,并注释掉使用MapHttpRoute创建的默认路由)
如果我用http://localhost/api/HelloMessage/1点击它,效果会非常好。
但是,如果我用http://localhost/api/HelloMessage?id=1命中它,它会绑定到无参数版本。我哪里错了?
一件奇怪的事情:
如果我重新启用MapHttpRoute代码,那么路由工作(所以?id = 1路由到参数化方法)。
我想知道为什么这不适用于基于属性的路由。这是一个错误,还是我做错了?
这里是MapHttpRoute代码,它将使其工作:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
答案 0 :(得分:1)
这是设计上的。默认的基于约定的路由会将api/{controller}/{id}
之类的路由映射到无参数操作,因为{id}
是可选的,如defaults: new { id = RouteParameter.Optional }
所述。
使用属性路由,您可以在路由过程中获得更多控制和灵活性。
例如,在属性路由中,您可以将id
设为可选,如此
[Route("api/HelloMessage/{id?}")]
public async Task<IHttpActionResult> Get(int id) {...}
但这会导致与第一条路线发生冲突,因为它们现在都匹配api/HelloMessage
。
如果你想通过从uri中检索id来使http://localhost/api/HelloMessage?id=1
工作,那么你需要首先删除没有参数的动作,或者改变它的路径以使其与众不同并制作另一个动作的id是可选的。
框架工作将URI中的?id=1
与参数匹配,并将值传递给参数。