OData in ASP.NET Core, pagination with total number of records in a table (Metadat missing)

Viewed 962

I'm using OData in my asp.net core3.1 app and what to delegate the pagination to the client. I'm stuck at how to return alog with the given number of entries, the total number of entries in a table. For example having a table with 100 entries, I want to be able to get this information to know exactly how to create my page component.

Service registration

services.AddOData();

Configuration

app.UseEndpoints(endpoints =>
{
    endpoints.MapDefaultControllerRoute();
    endpoints.EnableDependencyInjection();
    endpoints.Expand().Select().Count().Filter().OrderBy().SkipToken().MaxTop(20);
});

This is the endpoint

[HttpGet]
[EnableQuery]
[Produces("application/json")]
public IActionResult Get()
{
    var query = dbContext.Users;

    return Ok(query);
}

I'm using this query -

https://localhost:1234/api/users?$count=true&$select=id,name,version&$skip=0&$top=5

outputs just a list of 5 objects, no extra metadata.

[
   {
      Id: "1",
      Name: "a",
      Version: "1"
   },
   ... 4 more objects
]
1 Answers

$count=true means that the overall count will be in the response:

GET: ~/OData/Employees/Summaries?$count=true&$top=10&$skip=10
{
    "@odata.context": "~/odata/$metadata#EmployeeSummaryDTOs(Contact())",
    "@odata.count": 29,
    "value": [
        {
            "Id": 15097,
            "Title": "Miss Mavis MOPPIT",
    ...

We can actually cheat a little to prove this, if we take the $top 0 records, the count is still returned:

GET: ~/OData/Employees/Summaries?$count=true&$top=0
{
    "@odata.context": "~/odata/$metadata#EmployeeSummaryDTOs(Contact())",
    "@odata.count": 29,
    "value": []
}

This of course relys on a default or pass through controller, your controller method will need to return an IQueryable expression for the $count to be resolved automatically.

The default implementation will apply the $filter to your expression, then resolve the $count as a separate DB query, then it applies the paging Take/Skip logic when it retrieves the final result.

If you are processing the request yourself, then you will need to manage that logic as well.

Related