A Detailed Tutorial on Pagination for ASP.NET Core Web APIs 🚀
Tags: aspdotnet, api, tutorial, pagination
Published: 2024-05-25 16:10:33

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:



```shell

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`.



```csharp

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.



```csharp

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.



```csharp

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.



```csharp

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!