如何使用 OData 对 Dictionary<string, string> 进行 $filter?

Aar*_*ron 5 c# odata asp.net-web-api2

我的控制器上有一个启用 OData 查询的操作,该操作返回资产。

C# 模型。

var asset = new Asset()
{
    Id = Guid.NewGuid().ToString(),
    Name = "Cool Asset Yo",
    Url = "http://test/test.asset",
    Tags = new[] {"test"},
    Properties = new Dictionary<string, string>
    {
        {"platform", "android"},
        {"dim_depth", "1.0"},
        {"dim_height", "1.0"},
        {"dim_width", "1.0"},
        {"item_type", "Trim"}
    }
}
Run Code Online (Sandbox Code Playgroud)

返回的 JSON

 [
      {
        "name": "Cool Asset Yo",
        "properties": {
          "platform": "android",
          "dim_depth": "1.0",
          "dim_height": "1.0",
          "dim_width": "1.0",
          "item_type": "Trim"
        },
        "tags": [
          "test"
        ],
        "url": "http://test/test.asset",
        "id": "77d9b9df-4f4b-4fad-a1d3-af5075d52a62",
      }
 ]
Run Code Online (Sandbox Code Playgroud)

有效的示例查询!

  • api/Asset?$filter=startswith(name, 'Cool')
  • api/Asset?$filter=tags/any(tag eq 'test')
  • api/Asset?$filter=id eq '77d9b9df-4f4b-4fad-a1d3-af5075d52a62'

现在失败了:-(

  • api/Asset?$filter=properties/platform eq 'Android'
    • 错误:属性“平台”的属性访问的父值不是单个值。属性访问只能应用于单个值。
  • api/Asset?$filter=properties/any(props: props/platform eq 'Android')
    • 错误:在类型“System.Collections.Generic.KeyValuePair_2OfString_String”上找不到名为“platform”的属性。
  • api/Asset?$filter=properties/any(keyValue: keyValue('platform') eq 'Android')
    • 错误:发现名为“keyValue”的未知函数。这也可能是函数导入或导航属性上的键查找,这是不允许的。
  • api/Asset?$filter=properties/any(keyValue: keyValue eq 'Android')
    • 错误:检测到类型不兼容的二元运算符。找到运算符类型“Equal”的操作数类型“System.Collections.Generic.KeyValuePair_2OfString_String”和“Edm.String”。
  • api/Asset?$filter=properties['platform'] eq 'Android'
    • 错误:'properties['platform'] eq 'Android'' 中位置 31 处存在语法错误。

如何获取“Android”“平台”的资产列表?我在模型中使用通用词典的Microsoft 文档中看到示例,但没有看到任何 $filter 示例。

Sam*_* Xu 1

在您的场景中,“属性”看起来是字典属性,但字典属性不是 OData 中的内置属性。

此外,您的有效负载看起来是正常的 JSON 序列化输出。它不是 odata 有效负载。

您说您在模型中使用通用字典的 Microsoft 文档中看到了示例,这是动态属性的用法。请注意“您的场景(字典)和动态属性之间是不同的”。

最重要的是,Web API OData 现在支持对动态属性进行过滤。在提交中查看我的测试用例

希望它可以帮助你。