主要问题是 OData v4 规范是一个不断发展的标准,因为许多实现以不同的方式处理某些请求,要么是因为标准已更改,要么是因为标准难以实现,或者规范中建议的行为不符合其余约定。
为什么是这样?我是否误解了文档?
所以你的主要问题是你正在阅读wrong您正在查询的 API 的文档。重要的是要认识到,每次实施standard由开发人员决定他们与该标准的符合程度,因此您需要阅读专门与该 API 相关的文档。
这是 OData v4 的相关规范:
4.8 处理集合的计数 http://docs.oasis-open.org/odata/odata/v4.01/odata-v4.01-part2-url-conventions.html#sec_AddressingtheCountofaCollection
为了获取集合中项目数量的原始值,客户端将 /$count 附加到标识实体集或集合的 URL 的资源路径。
The /$count
路径后缀标识集合中记录的整数计数,不应与系统查询选项组合$top
, $skip
, $orderby
, $expand
, and $format
。计数不得受到影响$top
, $skip
, $orderby
, or $expand
。
应用任何后计算计数/$filter
路径段,或$filter
or $search
集合的系统查询选项。
在.Net实现中因为$count
是查询的结果,需要将其作为查询选项管道的一部分而不是路径的一部分进行评估。
MS OData 查询选项 - 计数 https://learn.microsoft.com/en-us/odata/concepts/queryoptions-overview#count
The $count
系统查询选项允许客户端请求响应中的资源中包含的匹配资源的计数。 $count 查询选项的布尔值为 true 或 false。
例子:
- 返回集合中的产品总数以及结果
http://host/service/Products?$count=true
- 可以通过指定来请求相关实体的计数
$count
内的查询选项$expand
条款。http://host/service/Categories?$expand=Products($count=true)
从实现的角度来看,混合这个查询选项进入path打破了用于所有其他处理和 url 解析的约定,这确实是一个奇怪的事情。路径和查询。
关于对象响应
在.Net实现中,因为$count
在集合扩展以及根上都受支持(请参阅第二个示例),他们选择将值作为与结果混合的元数据/属性注入。这样,响应对于序列化目的仍然有效,并且count无论在何处使用,行为都再次保持一致。
最后一个示例是我从我自己的一个 API 中为您提供的,演示了扩展集合的属性响应,如果$count=true
没有返回对象图,我将无法访问counts全部扩展:
https://localhost/OData/Residents?$count=true&$expand=Entity($select=Id;$expand=Contacts($count=true;$top=0))&$select=id&$top=2
{
"@odata.context": "https://localhost/odata/$metadata#Residents(Id,Entity(Id,Contacts()))",
"@odata.count": 29,
"value": [
{
"Id": 13110,
"Entity": {
"Id": 13110,
"[email protected] /cdn-cgi/l/email-protection": 6,
"Contacts": []
}
},
{
"Id": 13164,
"Entity": {
"Id": 13164,
"[email protected] /cdn-cgi/l/email-protection": 6,
"Contacts": []
}
}
],
"@odata.nextLink": "localhost/OData/Residents?$expand=Entity%28%24select%3DId%3B%24expand%3DContacts%28%24count%3Dtrue%3B%24top%3D0%29%29&$select=id&$top=2&$skip=2"
}