Items count in OData v4 WebAPI response

前端 未结 4 1824
野性不改
野性不改 2021-02-14 03:47

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

4条回答
  •  你的背包
    2021-02-14 04:25

    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 ApiControllers so you cannot have things like count or $metadata. If you choose to use simple ApiController the way above is the one you should use to return a count 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:

    • How to Use Web API OData to Build an OData V4 Service without Entity Framework
    • Web API OData V4 Pitfalls
    • Create an OData v4 Endpoint Using ASP.NET Web API 2.2

提交回复
热议问题