DEV Community

Cover image for A Brief Guide to Implementing Pagination in a C# Endpoint
Sean Drew
Sean Drew

Posted on • Edited on

A Brief Guide to Implementing Pagination in a C# Endpoint

Pagination is a crucial feature in APIs that deal with large datasets, ensuring efficient data delivery by dividing it into smaller, manageable chunks. This is a brief guide to implementing pagination in a C# API endpoint.

Understand the Pagination Basics
Pagination typically involves two parameters:

  • Page Number (page): Indicates which page to retrieve.
  • Page Size (pageSize): Specifies the number of records per page.

Example: If you have 100 records and a page size of 10:

  • page = 1 returns records 1–10.
  • page = 2 returns records 11–20.

Create the API Endpoint
Here's an example of a simple Web API endpoint that supports pagination.

[HttpGet("GetData")]
public async Task<IActionResult> GetData(int page = 1, int pageSize = 10)
{
  if (page <= 0 || pageSize <= 0)
  {
    return BadRequest("Page and PageSize must be greater than zero.");
  }

  int skip = (page - 1) * pageSize;

  // Mock data for demonstration
  var data = Enumerable.Range(1, 100).Select(x => new { Id = x, Value = $"Item {x}" });

  var paginatedData = data.Skip(skip).Take(pageSize).ToList();

  var response = new
  {
    TotalItems = data.Count(),
    Page = page,
    PageSize = pageSize,
    TotalPages = (int)Math.Ceiling(data.Count() / (double)pageSize),
    Data = paginatedData
  };

  return Ok(response);
}
Enter fullscreen mode Exit fullscreen mode

SQL Integration
Getting the data from a stored procedure. When working with databases, use OFFSET and FETCH clauses in SQL Server for efficient pagination.

Example of a stored procedure:

drop procedure if exists GetPagedData
go


create procedure GetPagedData
  @page int,
  @pagesize int
as
begin
  set nocount on

  declare @skip int = (@page - 1) * @pagesize

  select
  [id],
  [value]
  from [yourtable]
  order by [id]
  offset @skip rows
  fetch next @pagesize rows only
end
Enter fullscreen mode Exit fullscreen mode

Example of calling the stored procedure:
I typically use Visual Studio for my development, organizing shared methods (such as GetDataFromDb) in a dedicated class file. For the sake of clarity in documents like this, that methodology is not included.

[HttpGet("GetDataFromDb")]
public async Task<IActionResult> GetDataFromDb(int page = 1, int pageSize = 10)
{
  if (page <= 0 || pageSize <= 0)
  {
    return BadRequest("Page and PageSize must be greater than zero.");
  }

  using (var connection = new SqlConnection("YourConnectionString"))
  {
    var parameters = new DynamicParameters();
    parameters.Add("@Page", page);
    parameters.Add("@PageSize", pageSize);

    var data = await connection.QueryAsync<YourModel>(
      "GetPagedData", // the stored procedure
      parameters, 
      commandType: CommandType.StoredProcedure);

    return Ok(data);
  }
}
Enter fullscreen mode Exit fullscreen mode

Enhance the User Experience

  • Include total record counts in the response for better navigation on the client side.
  • Validate page and pageSize values to avoid exceptions or inefficiencies.
  • Cache frequently accessed pages to reduce database load.

Testing The Endpoint and Pagination
I usually use Postman to test endpoints during development, allowing me to experiment with different combinations of page and pageSize, while also verifying that edge cases (such as page = 0, pageSize = 0, or page > TotalPages) are handled correctly.

Conclusion
By integrating pagination into an API endpoint, you can improve performance and user experience significantly, especially when working with large datasets.

Top comments (0)