Web API OData Inlinecount无效

tom*_*tom 27 c# odata asp.net-web-api odata-v3

我在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();
     }
 }
Run Code Online (Sandbox Code Playgroud)

当我 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>
Run Code Online (Sandbox Code Playgroud)

我没有注释 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>
Run Code Online (Sandbox Code Playgroud)

我肯定有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'.
Run Code Online (Sandbox Code Playgroud)

有什么建议?

You*_*oui 26

好问题.

开箱即用$ inlinecount仅在您发回OData响应时有效.原因是OData定义了XML和JSON没有定义的数据中的特殊字段.所以在OData中,响应可能如下所示:

{
  "odata.metadata":"http://localhost:12345/odata/$metadata#Customers",
  "odata.count":"4",
  "value":[ ... ]
}
Run Code Online (Sandbox Code Playgroud)

注意带有"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());
}
Run Code Online (Sandbox Code Playgroud)

通过添加XML和JSON的包装器对象(包括Count和下一页链接),这应该适用于OData,JSON和XML.

  • 在这种情况下,文档是错误的.不同之处在于过滤不需要更改数据的"形状",但添加内联计数和下一页链接可以.所以过滤开箱即用于其他格式化程序,但$ inlinecount却没有. (3认同)
  • Fyi,你在答案中的链接(通过3个简单的步骤开始使用Odata)实现了ODataController/EntitySetController,它仍然存在由OP引发的示例问题.$ inlinecount仍无效. (3认同)
  • 默认情况下,@ GONeale Request.GetNextPageLink()和GetInlineCount()都为null.如果请求uri在查询字符串中有'?$ inlinecount = allpages',则GetInlineCount()将包含计数,并且只有在调用ApplyTo时设置ODataQuerySettings.PageSize时,GetNextPageLink()将包含下一页链接(使用重载获取查询设置对象),如果结果多于您设置的页面大小.那有意义吗? (2认同)

Jim*_*los 6

在OData v4中,$ inlinecount = allpages已由$ count = true代替。

$ count只能在最新版本的aspnet mvc中返回IQueryable。