In our last tutorial, we went over the repository pattern and how to create reusable code in our ASP.NET Core API. In this tutorial, we’re going to go over how to implement paging in our REST API. Normally when we are pulling a collection from our database, we don’t want to pull all of the rows from the table. This can impact the performance of the database because our table could end up having thousands of rows. Instead, we can control how many we take using Entity Framework. If you’re also interested in learning more in our video lessons, please click this link as well and sign up for our weekly course updates.

Paging Query Parameters

The first thing that we will modify is our query parameters for our route from the previous tutorial. Instead of pulling the full collection, we will specify how many items we want to take at a time as well as how many we want to skip. An example would be taking the first 5 and then skipping none. This will return the first 5 from our database. We can also take 5 after skipping the first 5.

        [HttpGet]
        public async Task<ActionResult<IEnumerable<Post>>> GetPost(int page = 0, int pageSize = 5)
        {
            var posts =  await _repository.FindAll<Post>();
            
            return posts;
        }

Even though we add these query parameters, they aren’t very useful unless we modify the query. Inside of our interface and our implementation, let’s create another method called FindPaged. We’ll take the two parameters in and run an EF query based on those.

public interface IRepository
    {
        Task<List<T>> FindAll<T>() where T : class;
        Task<T> FindById<T>(long id) where T : class;
        Task CreateAsync<T>(T entity) where T : class;
        Task UpdateAsync<T>(T entity) where T : class;
        Task DeleteAsync<T>(T entity) where T : class;

        Task<List<T>> FindPaged<T>(int page, int pageSize) where T : class;
    }
public async Task<List<T>> FindPaged<T>(int page, int pageSize) where T : class
        {
            return await this.dbContext.Set<T>().Skip(page * pageSize).Take(pageSize).ToListAsync();
        }

In order to get the number we want to skip, we take the page that we are on and multiply it by our page size. Now we can update out controller method and we should now be able to page based on our parameters.

// GET: api/Posts
        [HttpGet]
        public async Task<ActionResult<IEnumerable<Post>>> GetPost(int page = 0, int pageSize = 5)
        {
            //var posts =  await _repository.FindAll<Post>();

            //var otherPost = await _context.Post.Skip(page * pageSize).Take(pageSize).ToListAsync();
            var posts = await _repository.FindPaged<Post>(page, pageSize);
            return posts;
        }

Using a 3rd Party Package for ASP.NET Core Paging

Instead of implementing this yourself, there is also a package that allows for paging in ASP.NET Core. X.PagedList.Mvc.CoreLet’s add the package in and replace our implementation.

Inside of our interface, we will change it to return an IEnumerable. We will also use the ToPagedListAsync method.

Task<IEnumerable<T>> FindPaged<T>(int page, int pageSize) where T : class;

public async Task<IEnumerable<T>> FindPaged<T>(int page, int pageSize) where T : class
        {
            return await this.dbContext.Set<T>().ToPagedListAsync(page, pageSize);
        }

Inside of our controller, we’ll make sure to return an OkResult.

// GET: api/Posts
        [HttpGet]
        public async Task<ActionResult<IEnumerable<Post>>> GetPost(int page = 0, int pageSize = 5)
        {
            //var posts =  await _repository.FindAll<Post>();

            //var otherPost = await _context.Post.Skip(page * pageSize).Take(pageSize).ToListAsync();
            var posts = await _repository.FindPaged<Post>(page, pageSize);
            
            return Ok(posts);
        }

Now when we run the API request, we’ll get the expected result. 

Paged ASP.NET Core Request

 

 

Codebrains Newsletter

Get weekly dev news and tutorials.

Powered by ConvertKit