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
For future reference (OData v4):
First of all $inlinecount
it's not supported in OData v4
so you should use $count=true
instead.
Second, if you have a normal ApiController
and you return a type like IQueryable
this is the way you can attach a count
property to the returned result:
using System.Web.OData;
using System.Web.OData.Query;
using System.Web.OData.Extensions;
//[EnableQuery] // -> If you enable globally queries does not require this decorator!
public IHttpActionResult Get(ODataQueryOptions queryOptions)
{
var query = _peopleService.GetAllAsQueryable(); //Abstracted from the implementation of db access. Just returns IQueryable
var queryResults = (IQueryable)queryOptions.ApplyTo(query);
return Ok(new PageResult(queryResults, Request.ODataProperties().NextLink, Request.ODataProperties().TotalCount));
}
Note: OData functionality does not supported by
ApiController
s so you cannot have things likecount
or$metadata
. If you choose to use simpleApiController
the way above is the one you should use to return acount
property.
For a full support of OData functionality you should implement a ODataController
the following way:
PeopleController.cs
using System.Web.OData;
using System.Web.OData.Query;
public class PeopleController : ODataController
{
[EnableQuery(PageSize = 10, AllowedQueryOptions = AllowedQueryOptions.All)]
public IHttpActionResult Get()
{
var res = _peopleService.GetAllAsQueryable();
return Ok(res);
}
}
App_Start \ WebApiConfig.cs
public static void ConfigureOData(HttpConfiguration config)
{
//OData Models
config.MapODataServiceRoute(routeName: "odata", routePrefix: null, model: GetEdmModel(), batchHandler: new DefaultODataBatchHandler(GlobalConfiguration.DefaultServer));
config.EnsureInitialized();
}
private static IEdmModel GetEdmModel()
{
var builder = new ODataConventionModelBuilder
{
Namespace = "Api",
ContainerName = "DefaultContainer"
};
builder.EntitySet("People").EntityType.HasKey(item => item.Id); //I suppose the returning list have a primary key property(feel free to replace the Id key with your key like email or whatever)
var edmModel = builder.GetEdmModel();
return edmModel;
}
Then you access your OData Api this way (example):
encoded uri:
http://localhost:/People/?%24count=true&%24skip=1&%24top=3
decoded:
http://localhost:/People/?$count=true&$skip=1&$top=3
References: