Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pagination in a .NET Core API Project

I am trying to implement pagination on .NET Core RESTful API's (with EF).

Rather than re-inventing the wheel, I was hoping there was a way to either use a generic function that could hook into the API handler and intercept requests to apply them to EF Query results or something built into .NET Core that I am un-aware of. Can anyone point me in the general direction of a library that they are aware of that does this in .NET Core

The way I would previously do this (and have done in non .NET Core apps) is to make a function that I have to physically add the parameters to the controller function (pageSize, pageNumber) which does get tedious (and I think a tad untidy) to add these two parameters to every single function.

like image 753
John Mitchell Avatar asked May 02 '17 10:05

John Mitchell


People also ask

How can we implement pagination in asp net core?

How to implement paging in ASP.NET Core Web API. In an empty project, update the Startup class to add services and middleware for MVC. Add models to hold link and paging data. Create a type to hold the paged list.

What is pagination in Web API?

Pagination is the process of splitting data into discrete pages, and you should implement it when you are building RESTful Web APIs that potentially serve huge amount of data. Imagine you have thousands or maybe millions of records in your database and your API endpoint try to return all of them at once.

How pagination is implemented?

For example, you can implement pagination using links to new pages on your ecommerce site, or using JavaScript to update the current page. Load more and infinite scroll are generally implemented using JavaScript.


1 Answers

There is no built-in feature far pagination, and if you wont like it. Imagine a controller method returning 1.000.000 results for pagination just to pick 10 from them. It is up to you to implement the pagination.

The tedious and untidy controller methods like

public class FooController : Controller
{
    public IEnumerable<Foo> GetAll( 
        string Filter, 
        string Whatever, 
        ..., 
        int pageNumber = 1, 
        int pageSize = 20 ) 
    { ... }
}

can be reorganized to

public class FooController : Controller
{
    public IEnumerable<Foo> GetAll( GetAllArgs args ) 
    {
        IQueryable<Foo> query = ...

        return query.Paginate( args ).ToList();  
    }

    public class GetAllArgs : QueryArgsBase
    {
        public string Filter { get; set; }
        public string Whatever { get; set; }
    }
}

public interface IPaginationInfo
{ 
    int PageNumber { get; }
    int PageSize { get; }
}

public abstract class QueryArgsBase : IPaginationInfo
{
    public int PageNumber { get; set; } = 1;
    public int PageSize { get; set; } = 20;
}

public static class QueryableExtensions
{
    public static IQueryable<T> Paginate<T>( 
        this IQueryable<T> source, 
        IPaginationInfo pagination )
    {
        return source
            .Skip( ( pagination.PageNumber - 1 ) * pagination.PageSize )
            .Take( pagination.PageSize );
    }
}

Change any other controller method to have such an argument class and inherite from QueryArgsBase or implement IPaginationInfo to use the QueryableExtensions.Paginate method.

like image 60
Sir Rufo Avatar answered Oct 02 '22 19:10

Sir Rufo