Web API OData V3 `$inlinecount` 失败
Posted
技术标签:
【中文标题】Web API OData V3 `$inlinecount` 失败【英文标题】:Web API OData V3 `$inlinecount` fails 【发布时间】:2013-03-03 14:27:26 【问题描述】:我在 ASP.NET Web API 应用程序中使用开箱即用的 ValuesController
public class ValuesController : ApiController
// GET api/values
[Queryable(PageSize = 1)]
public IQueryable<string> Get()
return new string[] "value1", "value2", "value3", "value4", "value5" .AsQueryable();
当我get http://localhost/api/values?$inlinecount=allpages
这是回复
<ArrayOfString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<string>value1</string>
</ArrayOfString>
我已取消注释config.EnableQuerySupport();
过滤、排序工作正常。
如果我尝试 get http://localhost/api/values?$inlinecount=XXXXX
我会得到一个异常,所以 Web API 应用程序似乎知道 inlinecount
<Message>The query specified in the URI is not valid.</Message>
<ExceptionMessage>'xxx' is not a valid value for $inlinecount.</ExceptionMessage>
<ExceptionType>Microsoft.Data.OData.ODataException</ExceptionType>
我肯定有 Microsoft.AspNet.WebApi.OData 包 - 这是包管理器控制台的输出
PM> Install-Package Microsoft.AspNet.WebApi.OData
Attempting to resolve dependency 'Microsoft.Net.Http (= 2.0.20710.0 && < 2.1)'.
Attempting to resolve dependency 'Microsoft.AspNet.WebApi.Client (= 4.0.20710.0 && < 4.1)'.
Attempting to resolve dependency 'Newtonsoft.Json (= 4.5.6)'.
Attempting to resolve dependency 'Microsoft.AspNet.WebApi.Core (= 4.0.20710.0 && < 4.1)'.
Attempting to resolve dependency 'Microsoft.Data.OData (= 5.2.0 && < 5.3.0)'.
Attempting to resolve dependency 'System.Spatial (= 5.2.0)'.
Attempting to resolve dependency 'Microsoft.Data.Edm (= 5.2.0)'.
'Microsoft.AspNet.WebApi.OData 4.0.0' already installed.
WebServicesProject already has a reference to 'Microsoft.AspNet.WebApi.OData 4.0.0'.
有什么建议吗?
【问题讨论】:
【参考方案1】:在 OData v4 中,$inlinecount=allpages 已替换为 $count=true。
$count 仅适用于在最新版本的 aspnet mvc 中返回 IQueryable。
【讨论】:
【参考方案2】:好问题。
$inlinecount 开箱即用仅在您发回 OData 响应时有效。原因是 OData 在数据中定义了 XML 和 JSON 未定义的特殊字段。因此,在 OData 中,响应可能如下所示:
"odata.metadata":"http://localhost:12345/odata/$metadata#Customers",
"odata.count":"4",
"value":[ ... ]
注意带有“odata.count”属性的包装器。这与默认 XML 和 JSON 格式化程序写出数据的方式不同,因为它们没有针对这些附加信息的包装器。所以其他格式化程序默认不变。
现在你有几个选择:
您可以选择使用 OData 格式。为此,您需要按照此博文中的说明进行操作:
http://blogs.msdn.com/b/webdev/archive/2013/01/29/getting-started-with-asp-net-webapi-odata-in-3-simple-steps.aspx
您也可以选择返回 PageResult<T>
。这看起来像这样:
public PageResult<Customer> Get(ODataQueryOptions<Customer> queryOptions)
IQueryable results = queryOptions.ApplyTo(_customers.AsQueryable());
return new PageResult<Customer>(results as IEnumerable<Customer>, Request.GetNextPageLink(), Request.GetInlineCount());
通过为 XML 和 JSON 添加一个可以包含计数和下一页链接的包装器对象,这应该适用于 OData、JSON 和 XML。
【讨论】:
通过阅读 asp.net/web-api/overview/odata-support-in-aspnet-web-api/… 上的 MS 文档,听起来它应该开箱即用,比如过滤和排序? 在这种情况下文档是错误的。不同之处在于过滤不需要改变数据的“形状”,但是添加一个内联计数和一个下一页链接就可以了。所以过滤对其他格式化程序来说是开箱即用的,但 $inlinecount 不行。 看看微风js.com。最新版本适用于所有 MS OData 语法,并且都支持内联计数、选择和展开。 @GONeale Request.GetNextPageLink() 和 GetInlineCount() 默认为空。如果请求 uri 在查询字符串中有 '?$inlinecount=allpages',则 GetInlineCount() 将包含计数,并且 GetNextPageLink() 仅当您在调用 ApplyTo 时设置 ODataQuerySettings.PageSize 时才会包含下一页链接(使用重载获取查询设置对象)以及结果是否超过您设置的页面大小。这有意义吗? 仅供参考,您在答案中的链接(通过 3 个简单步骤开始使用 Odata)实现 ODataController / EntitySetController 仍然存在 OP 提出的示例问题。 $inlinecount 仍然不起作用。以上是关于Web API OData V3 `$inlinecount` 失败的主要内容,如果未能解决你的问题,请参考以下文章
[转]Web Api系列教程第2季(OData篇)——使用Web Api创建只读的OData服务