A Detailed Tutorial on Pagination for ASP.NET Core Web APIs

May 24, 2024 | .NET

Pagination and Filtering implementation in an API is a common practice to optimize responses and efficiently handle large datasets. Here’s a step-by-step guide on how to achieve this in an ASP.NET Core Web API from beginners to intermediate developers.

Setting Up Your ASP.NET Core Web API Project

Step 1: Start creating a New ASP.NET Core Web API Project

First things first, we need to create our project. You can do this using Visual Studio or the command line interface. For the CLI, simply run:

dotnet new webapi -n PaginationSample

Open the created folder and get coding!

Step 2: Define Your Model Class

Next, we’ll define a model class that will represent our data. For this example, let’s create a class named ListCSharpCornerArticles.

public class ListCSharpCornerArticles

{

    public int Id { get; set; }

    public string Title { get; set; }

    public string Category { get; set; }

}

This class has three properties: Id, Title, and Category. Simple and straightforward!

Creating and Configuring Middleware

Step 3: Create Custom Middleware for Logging Incoming Requests

Middleware is like the bouncer at a club—it controls what happens with each request before it reaches the controller. Let’s create a custom logging middleware.

using Microsoft.AspNetCore.Builder;

using Microsoft.AspNetCore.Http;

using Microsoft.Extensions.Logging;

using System.Threading.Tasks;



public class RequestLoggingMiddleware

{

    private readonly RequestDelegate _next;

    private readonly ILogger<RequestLoggingMiddleware> _logger;



    public RequestLoggingMiddleware(RequestDelegate next, ILogger<RequestLoggingMiddleware> logger)

    {

        _next = next;

        _logger = logger;

    }



    public async Task Invoke(HttpContext context)

    {

        _logger.LogInformation($"Request: {context.Request.Method} {context.Request.Path}");

        await _next(context);

    }

}

This middleware logs the HTTP method and the request path. Handy for debugging, right?

Step 4: Configure the Custom Middleware

Now that we have the middleware, let’s configure our application to use it. This involves modifying the Startup.cs file.

using Microsoft.AspNetCore.Builder;

using Microsoft.AspNetCore.Hosting;

using Microsoft.Extensions.Configuration;

using Microsoft.Extensions.DependencyInjection;

using Microsoft.Extensions.Hosting;



public class Startup

{

    public IConfiguration Configuration { get; }



    public Startup(IConfiguration configuration)

    {

        Configuration = configuration;

    }



    public void ConfigureServices(IServiceCollection services)

    {

        services.AddControllers();

        services.AddLogging();

    }



    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

    {

        if (env.IsDevelopment())

        {

            app.UseDeveloperExceptionPage();

        }



        app.UseMiddleware<RequestLoggingMiddleware>();



        app.UseRouting();

        app.UseEndpoints(endpoints =>

        {

            endpoints.MapControllers();

        });

    }

}

Now, every incoming request will be logged!

Implementing Pagination and Filtering in the Controller

Step 5: Create a Controller That Handles Pagination and Filtering

Finally, let’s put it all together in a controller.

using Microsoft.AspNetCore.Mvc;

using System;

using System.Collections.Generic;

using System.Linq;



[ApiController]

[Route("api/[controller]")]

public class CSharpCornerArticlesController : ControllerBase

{

    private static List<ListCSharpCornerArticles> _articles = GenerateSampleArticles();



    private static List<ListCSharpCornerArticles> GenerateSampleArticles()

    {

        // Generate and return sample articles

        return new List<ListCSharpCornerArticles>

        {

            new ListCSharpCornerArticles { Id = 1, Title = "Introduction to ASP.NET Core", Category = "ASP.NET Core" },

            new ListCSharpCornerArticles { Id = 2, Title = "Advanced C# Techniques", Category = "C#" },

            // Add more sample articles

        };

    }



    [HttpGet]

    public IActionResult Get([FromQuery] int page = 1, [FromQuery] int pageSize = 10, [FromQuery] string filter = "")

    {

        var query = _articles.AsQueryable();



        if (!string.IsNullOrEmpty(filter))

        {

            query = query.Where(article => article.Title.Contains(filter) || article.Category.Contains(filter));

        }



        var totalCount = query.Count();

        var totalPages = (int)Math.Ceiling((double)totalCount / pageSize);



        query = query.Skip((page - 1) * pageSize).Take(pageSize);



        var result = new

        {

            TotalCount = totalCount,

            TotalPages = totalPages,

            CurrentPage = page,

            PageSize = pageSize,

            Articles = query.ToList()

        };



        return Ok(result);

    }

}

In this controller, we handle both pagination and filtering. The Get endpoint takes page, pageSize, and filter as query parameters, filters the articles accordingly, and returns a user-friendly paginated result.

Conclusion

By now, you’ve got a robust understanding of how to implement pagination and filtering in an ASP.NET Core Web API. Not only have you learned how to structure your data, but you’ve also picked up on creating custom middleware for better logging and debugging. Here’s a quick recap:

  • Pagination helps divide large datasets into manageable chunks.
  • Filtering lets users request specific subsets of data.
  • Combining both techniques enhances performance and usability.

Organize your API with pagination and filtering and make your life (and your users’ lives) easier!

You May Also Like

Sign up For Our Newsletter

Weekly .NET Capsules: Short reads for busy devs.

  • NLatest .NET tips and tricks
  • NQuick 5-minute reads
  • NPractical code snippets
.