Asp.net Core 3.1 Binding:在GET中使用Dictionary作为参数的操作



我们正在定义一个操作,它将用于搜索存储在存储库中的文档;该接口允许指定筛选器列表以缩小结果范围。

[Route("search")]
[HttpGet]
[ProducesResponseType(typeof(List<DocumentDto>), (int)HttpStatusCode.OK)]
public async Task<ActionResult<DocumentDto>> GetDocuments(
[FromServices] IDocumentManager documentManager,
[FromQuery] Dictionary<string, string> filters)
{
//Do something
}

我们在动作签名中使用像Dictionary<string, string> filters这样的参数,因为我们想使用GET方法实现搜索,但使用动态参数列表。
过滤器只是一个key:value对象的列表,动作将传递给数据库,数据库是唯一知道如何处理它们的层。
我们这样使用调用url的服务:

/search?filter1=value1&filter2=value2&filter3=value3

绑定似乎"有效"。filters填充如下:

filters
[0] {[filter1, value1]}
[1] {[filter2, value2]}
[2] {[filter3, value3]}

检查与字典相关的绑定章节,似乎没有像我们这样在查询字符串中传递参数。

我们是否看到了绑定的副作用?
我们用来从查询字符串传递过滤器到字典的语法是否支持?

这样使用绑定多少有点问题。控制器上的字典正在捕获所有查询参数,因此,如果您的查询字符串为:

/search?filter1=value1&filter2=value2&filter3=value3&random=randomValue

你会在字典里看到:

filters
[0] {[filter1, value1]}
[1] {[filter2, value2]}
[2] {[filter3, value3]}
[3] {[random, randomValue]}

时,ASP。. NET Core为一个参数创建模型绑定的上下文,模型名来自其中一个来源:

  1. 显式名称(如[FromQuery(Name = ...)]
  2. )
  3. 来自值提供程序(在本例中为QueryStringValueProvider)

在您的示例中,上述内容都不为真,因此绑定上下文中的模型名称将为空。这会导致DictionaryModelBinder将查询字符串中的任意参数填充到字典中。

我建议按照你引用的文档来固定你的查询字符串。

最新更新