Web API OData V3中的`$inlinecount`失败

27

我正在使用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();
     }
 }

当我调用 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'.
任何建议?
2个回答

28

好问题。

$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添加一个包装对象,可以包含Count和下一页链接,这对于OData、JSON和XML应该可以很好地工作。


1
从阅读此链接中的MS文档http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options,似乎它应该开箱即用,如过滤和排序? - tom
3
在这种情况下,文件有误。不同之处在于,筛选不需要改变数据的“形状”,但是添加内联计数和下一页链接需要改变数据的“形状”。因此,筛选器适用于其他格式化程序,但$inlinecount则不适用。 - Youssef Moussaoui
请查看breezejs.com。最新版本支持所有MS OData语法,同时支持inlinecount、select和expand。 - Jay Traband
2
@GONeale Request.GetNextPageLink() 和 GetInlineCount() 默认都是 null。如果请求 URI 中的查询字符串包含 '?$inlinecount=allpages',则 GetInlineCount() 将包含计数;如果您在调用 ApplyTo 时设置了 ODataQuerySettings.PageSize(使用接受查询设置对象的重载),并且结果数量超过您设置的页面大小,则 GetNextPageLink() 将仅包含下一页链接。这样说清楚了吗? - Youssef Moussaoui
3
请注意,你在回答中提供的链接("3个简单步骤入门OData")实现了ODataController/EntitySetController,但仍存在OP提出的问题。$inlinecount仍然无法使用。 - stack247
显示剩余3条评论

10
在OData v4中,$inlinecount=allpages 已被 $count=true 取代。
在最近版本的 aspnet mvc 中,$count 仅适用于返回 IQueryable。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接