WebAPI 2.2,基于属性的路由和查询字符串

时间:2016-07-07 23:52:07

标签: c# asp.net-web-api

我使用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 }
    );

1 个答案:

答案 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与参数匹配,并将值传递给参数。