Implementing Pagination and Filtering in ASP.NET Core 8.0 API

Introduction

As applications grow in complexity and scale, managing large datasets becomes crucial for both performance and user experience. Pagination and filtering are essential techniques to efficiently handle and display large amounts of data. This article will guide you through implementing pagination and filtering in an ASP.NET Core 8.0 API using Entity Framework Core (EF Core).

Setting Up the Project
 

1. Create a New ASP.NET Core Project

create a new ASP.NET Core Web API project.

dotnet new webapi -n PaginationFilteringDemo
cd PaginationFilteringDemo

2. Add Entity Framework Core

Install the necessary EF Core packages.

dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools

3. Configure the Database Context

Create a Models folder and add an Item class.

namespace PaginationFilteringDemo.Models
{
    public class Item
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public decimal Price { get; set; }
        public string Category { get; set; }
    }
}

Create an ApplicationDbContext class in the Data folder.

using Microsoft.EntityFrameworkCore;
using PaginationFilteringDemo.Models;

namespace PaginationFilteringDemo.Data
{
    public class ApplicationDbContext : DbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }

        public DbSet<Item> Items { get; set; }
    }
}

Update appsettings.json with the connection string.

"ConnectionStrings": {
    "DefaultConnection": "your connection string"
}

Configure the database context in Program.cs.

using Microsoft.EntityFrameworkCore;
using PaginationFilteringDemo.Data;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();

Let's start implementing pagination
 

1. Create a Pagination Model

Create a PaginationParams class to define pagination parameters.

namespace PaginationFilteringDemo.Models
{
    public class PaginationParams
    {
        private const int MaxPageSize = 50;
        public int PageNumber { get; set; } = 1;

        private int _pageSize = 10;
        public int PageSize
        {
            get => _pageSize;
            set => _pageSize = (value > MaxPageSize) ? MaxPageSize : value;
        }
    }
}

2. Add a Paged Response Class

Create a PagedResponse class to structure the paginated response.

using System.Collections.Generic;
namespace PaginationFilteringDemo.Models
{
    public class PagedResponse<T>
    {
        public List<T> Data { get; set; }
        public int PageNumber { get; set; }
        public int PageSize { get; set; }
        public int TotalRecords { get; set; }

        public PagedResponse(List<T> data, int pageNumber, int pageSize, int totalRecords)
        {
            Data = data;
            PageNumber = pageNumber;
            PageSize = pageSize;
            TotalRecords = totalRecords;
        }
    }
}

3. Modify the Controller

Create a controller and name the ItemController.

using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using PaginationFilteringDemo.Data;
using PaginationFilteringDemo.Models;

namespace PaginationFilteringDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ItemsController : ControllerBase
    {
        private readonly ApplicationDbContext _context;

        public ItemsController(ApplicationDbContext context)
        {
            _context = context;
        }

        [HttpGet]
        public async Task<ActionResult<PagedResponse<Item>>> GetItems([FromQuery] PaginationParams paginationParams)
        {
            var query = _context.Items.AsQueryable();
            var totalRecords = await query.CountAsync();
            var items = await query.Skip((paginationParams.PageNumber - 1) * paginationParams.PageSize)
                                    .Take(paginationParams.PageSize)
                                    .ToListAsync();

            var pagedResponse = new PagedResponse<Item>(items, paginationParams.PageNumber, paginationParams.PageSize, totalRecords);

            return Ok(pagedResponse);
        }
    }
}

Filtering
 

1. Add Filtering Parameters

Extend the PaginationParams class to include filtering parameters.

namespace PaginationFilteringDemo.Models
{
    public class PaginationParams
    {
        private const int MaxPageSize = 50;
        public int PageNumber { get; set; } = 1;

        private int _pageSize = 10;
        public int PageSize
        {
            get => _pageSize;
            set => _pageSize = (value > MaxPageSize) ? MaxPageSize : value;
        }

        public string SearchTerm { get; set; }
        public string Category { get; set; }
    }
}

2. Update the Controller for Filtering

[HttpGet]
public async Task<ActionResult<PagedResponse<Item>>> GetItems([FromQuery] PaginationParams paginationParams)
{
    var query = _context.Items.AsQueryable();

    if (!string.IsNullOrEmpty(paginationParams.SearchTerm))
    {
        query = query.Where(i => i.Name.Contains(paginationParams.SearchTerm));
    }

    if (!string.IsNullOrEmpty(paginationParams.Category))
    {
        query = query.Where(i => i.Category == paginationParams.Category);
    }

    var totalRecords = await query.CountAsync();
    var items = await query.Skip((paginationParams.PageNumber - 1) * paginationParams.PageSize)
                           .Take(paginationParams.PageSize)
                           .ToListAsync();

    var pagedResponse = new PagedResponse<Item>(items, paginationParams.PageNumber, paginationParams.PageSize, totalRecords);

    return Ok(pagedResponse);
}

Conclusion

Implementing pagination and filtering in an ASP.NET Core 8.0 API using EF Core ensures that your application can handle large datasets efficiently. By following this guide, you can create a robust API that delivers data in a manageable and user-friendly manner.

Happy Coding!


Similar Articles