How to return number of items in OData v4 HTTP response?
I need this number to pagination, so it should be number of items after filtering, but before 'skip' and 'top'.
I already tried passing '$inlinecount=allpages' and '$count=true' parameters in query options in url (https://damienbod.wordpress.com/2014/06/13/web-api-and-odata-v4-queries-functions-and-attribute-routing-part-2/ - "Example of $count"), but my responses from WebAPI always have only query results (collection) - whole response looks like:
[
{
"Name":"name1",
"age":5
},
{
"Name":"name2",
"age":15
}
]
There is nothing like "odata.count" in the response.
I also tried returning PageResult instead of IQueryable in my WebAPI controller action (like described here: http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/supporting-odata-query-options#server-paging), but Request.GetInlineCount() is deprecated and its value is always null.
Any ideas?
[Update] I just found the same problem here: WebApi with Odata NextPage and Count not appearing in the JSON response and I removed [EnableQuery] attribute and now my response looks like:
{
"Items":
[
{
"Name":"name1",
"age":5
},
{
"Name":"name2",
"age":15
}
],
"NextPageLink":null,
"Count":null
}
But still "Count" is always null. :(
Edit: After debugging and searching for count value in Request properties in my controller, I found out that correct Count value is in property named "System.Web.OData.TotalCount". So right now I exctract this value from that request property and my controller looks like that:
public PageResult<People> Get(ODataQueryOptions<People> queryOptions)
{
var query = _context.People.OrderBy(x => x.SomeProperty);
var queryResults = (IQueryable<People>)queryOptions.ApplyTo(query);
long cnt = 0;
if (queryOptions.Count != null)
cnt = long.Parse(Request.Properties["System.Web.OData.TotalCount"].ToString());
return new PageResult<People>(queryResults, null, cnt);
}
And it works fine, but I still don't know why I have to use workarounds like that.
For future reference (OData v4):
First of all
$inlinecount
it's not supported inOData v4
so you should use$count=true
instead.Second, if you have a normal
ApiController
and you return a type likeIQueryable<T>
this is the way you can attach acount
property to the returned result:For a full support of OData functionality you should implement a
ODataController
the following way:PeopleController.cs
App_Start \ WebApiConfig.cs
Then you access your OData Api this way (example):
encoded uri:
decoded:
References:
Will you please take a look at the sample service TripPin web api implementation at https://github.com/OData/ODataSamples/blob/master/Scenarios/TripPin. You can follow the code in Airports controller and the service with the code http://services.odata.org/TripPinWebApiService/Airports?$count=true can return the count correctly.
This can also be achieved by an action filter:
And the custom PageResult class is:
Usage:
That's what I am using with oData v4: