Asp.net 核心 3.1 绑定:在 GET 中使用字典作为参数的操作

Asp.net Core 3.1 Binding: Action with a Dictionary as parameter in GET

我们正在定义将用于搜索存储在存储库中的文档的操作;该界面允许指定过滤器列表以缩小结果范围。

[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]}

查看与字典相关的binding chapter,似乎没有记录我们正在做的查询字符串中传递的参数。

我们看到有约束力的副作用了吗?
我们用来将过滤器从查询字符串传递到字典的语法是否受支持?

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

/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为参数创建模型绑定上下文时,模型名称comes from one of the sources:

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

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

我建议根据您引用的文档修复您的查询字符串。