如何使用 OData 在 Dictionary<string, string> 上进行 $filter?
How can I $filter on Dictionary<string, string> using OData?
我的控制器上有一个启用了 OData 查询的操作,Returns 一个资产。
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"}
}
}
返回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",
}
]
有效的示例查询!
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'
- 错误:属性 访问 属性 'platform' 的父值不是单个值。 属性 访问只能应用于单个值。
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 处的语法错误
如何获取 'platform' 或 'Android' 的资产列表?我在模型中使用的通用词典 Microsoft Documents 中看到示例,我没有看到任何 $filter 示例。
在您的场景中,"Properties" 看起来是字典 属性,但字典 属性 不是 OData 中的内置 属性。
此外,您的负载看起来是正常的 JSON 序列化输出。这不是 odata 负载。
你说你在Microsoft Documents of Generic Dictionaries being used in a model中看到了例子,这是动态属性的用法。请注意“你的场景(字典)和动态属性是不同的”。
最重要,Web API OData 现在支持动态过滤属性。
在 commit
中查看我的测试用例
希望对您有所帮助。
Sam Xu 是正确的,OData 不支持字典 属性,动态 属性 在我的场景中也不起作用。我被迫将我的属性包更改为自定义键值类型的列表。
C# 模型。
var asset = new Asset()
{
Id = Guid.NewGuid().ToString(),
Name = "Cool Asset Yo",
Url = "http://test/test.asset",
Tags = new[] {"test"},
Properties = new List<KeyValue>
{
new KeyValue("platform", "android"),
new KeyValue("dim_depth", "1.0"),
new KeyValue("dim_height", "1.0"),
new KeyValue("dim_width", "1.0"),
new KeyValue("item_type", "Trim")
}
}
返回JSON
[
{
"name": "Cool Asset Yo",
"properties": [
{
"key": "platform",
"value": "android"
},
{
"key": "dim_depth",
"value": "1.0"
},
{
"key": "dim_height",
"value": "1.0"
},
{
"key": "dim_width",
"value": "1.0"
},
{
"key": "item_type",
"value": "Trim"
}
],
"tags": [
"test"
],
"url": "http://test/test.asset",
"id": "77d9b9df-4f4b-4fad-a1d3-af5075d52a62",
}
]
有效的示例查询!
api/Asset?$filter=properties/any(keyValue: keyValue/key eq 'platform' and keyValue/value eq '50129486')
我的控制器上有一个启用了 OData 查询的操作,Returns 一个资产。
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"}
}
}
返回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",
}
]
有效的示例查询!
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'
- 错误:属性 访问 属性 'platform' 的父值不是单个值。 属性 访问只能应用于单个值。
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 处的语法错误
如何获取 'platform' 或 'Android' 的资产列表?我在模型中使用的通用词典 Microsoft Documents 中看到示例,我没有看到任何 $filter 示例。
在您的场景中,"Properties" 看起来是字典 属性,但字典 属性 不是 OData 中的内置 属性。
此外,您的负载看起来是正常的 JSON 序列化输出。这不是 odata 负载。
你说你在Microsoft Documents of Generic Dictionaries being used in a model中看到了例子,这是动态属性的用法。请注意“你的场景(字典)和动态属性是不同的”。
最重要,Web API OData 现在支持动态过滤属性。 在 commit
中查看我的测试用例希望对您有所帮助。
Sam Xu 是正确的,OData 不支持字典 属性,动态 属性 在我的场景中也不起作用。我被迫将我的属性包更改为自定义键值类型的列表。
C# 模型。
var asset = new Asset()
{
Id = Guid.NewGuid().ToString(),
Name = "Cool Asset Yo",
Url = "http://test/test.asset",
Tags = new[] {"test"},
Properties = new List<KeyValue>
{
new KeyValue("platform", "android"),
new KeyValue("dim_depth", "1.0"),
new KeyValue("dim_height", "1.0"),
new KeyValue("dim_width", "1.0"),
new KeyValue("item_type", "Trim")
}
}
返回JSON
[
{
"name": "Cool Asset Yo",
"properties": [
{
"key": "platform",
"value": "android"
},
{
"key": "dim_depth",
"value": "1.0"
},
{
"key": "dim_height",
"value": "1.0"
},
{
"key": "dim_width",
"value": "1.0"
},
{
"key": "item_type",
"value": "Trim"
}
],
"tags": [
"test"
],
"url": "http://test/test.asset",
"id": "77d9b9df-4f4b-4fad-a1d3-af5075d52a62",
}
]
有效的示例查询!
api/Asset?$filter=properties/any(keyValue: keyValue/key eq 'platform' and keyValue/value eq '50129486')