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!
Top comments (2)
Will using
yield return
work for the same purpose?Hi @kimfom01 thanks for your comment. Regarding to your question using
yield return
can certainly work for similar purposes, especially when handling large datasets.yield return
allows you to stream data one item at a time, which can be particularly useful for scenarios where you want to improve memory efficiency and reduce the initial response times for large collections.In the context of an ASP.NET Core Web API, you could leverage
yield return
to implement pagination more efficiently.If you have any doubt, just let us know!