C# - Pure Pagination Logic in C# / ASP.NET
Below is a pure pagination function written in C# that you can use to paginate any array or list of items in ASP.NET Core and standard ASP.NET applications.
It's available as a NuGet package at https://www.nuget.org/packages/JW.Pager, you can add it to your ASP.NET Core project with the .NET Core CLI by running dotnet add package JW.Pager
. For standard ASP.NET projects you can use the NuGet package manager console in visual studio to run Install-Package JW.Pager
.
Source code for the C# pagination logic is available on GitHub at https://github.com/cornflourblue/JW.Pager
For an example ASP.NET Core Razor Pages project that uses the pagination package check out ASP.NET Core Razor Pages - Pagination Example
For the same pagination logic written in JavaScript check out JavaScript - Pure Pagination Logic in Vanilla JS
C# / ASP.NET Pager Class Usage
The C# pagination logic is contained in a single Pager
class that takes the following constructor arguments:
totalItems
(required) - the total number of items to be pagedcurrentPage
(optional) - the current active page, defaults to the first pagepageSize
(optional) - the number of items per page, defaults to 10maxPages
(optional) - the maximum number of page navigation links to display, defaults to 10
After creating an instance of the Pager
class with new Pager(...)
, it populates a bunch of properties on the class instance with all the information needed to display the current page of items in the view and the page navigation links.
Below are some example inputs and outputs to give you a better idea of how the Pager
class works, you can tinker with them in the example ASP.NET Core Razor Pages project linked to above.
var pager = new Pager(totalItems: 150);
// pager instance property values
pager.TotalItems; // 150
pager.CurrentPage; // 1
pager.PageSize; // 10,
pager.TotalPages; // 15
pager.StartPage; // 1
pager.EndPage; // 10
pager.StartIndex; // 0
pager.EndIndex; // 9
pager.Pages; // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
var pager = new Pager(totalItems: 150, currentPage: 7);
// pager instance property values
pager.TotalItems; // 150
pager.CurrentPage; // 7
pager.PageSize; // 10,
pager.TotalPages; // 15
pager.StartPage; // 2
pager.EndPage; // 11
pager.StartIndex; // 60
pager.EndIndex; // 69
pager.Pages; // [ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 ]
var pager = new Pager(totalPages: 150, currentPage: 7, pageSize: 15);
// pager instance property values
pager.TotalItems; // 150
pager.CurrentPage; // 7
pager.PageSize; // 15,
pager.TotalPages; // 10
pager.StartPage; // 1
pager.EndPage; // 10
pager.StartIndex; // 90
pager.EndIndex; // 104
pager.Pages; // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
var pager = new Pager(totalPages: 150, currentPage: 7, pageSize: 15, maxPages: 5);
// pager instance property values
pager.TotalItems; // 150
pager.CurrentPage; // 7
pager.PageSize; // 15,
pager.TotalPages; // 10
pager.StartPage; // 5
pager.EndPage; // 9
pager.StartIndex; // 90
pager.EndIndex; // 104
pager.Pages; // [ 5, 6, 7, 8, 9 ]
C# / ASP.NET Pagination Logic
Below are the nuts and bolts of how the pagination logic is implemented in C# / ASP.NET.
using System;
using System.Collections.Generic;
using System.Linq;
namespace JW
{
public class Pager
{
public Pager(
int totalItems,
int currentPage = 1,
int pageSize = 10,
int maxPages = 10)
{
// calculate total pages
var totalPages = (int)Math.Ceiling((decimal)totalItems / (decimal)pageSize);
// ensure current page isn't out of range
if (currentPage < 1)
{
currentPage = 1;
}
else if (currentPage > totalPages)
{
currentPage = totalPages;
}
int startPage, endPage;
if (totalPages <= maxPages)
{
// total pages less than max so show all pages
startPage = 1;
endPage = totalPages;
}
else
{
// total pages more than max so calculate start and end pages
var maxPagesBeforeCurrentPage = (int)Math.Floor((decimal)maxPages / (decimal)2);
var maxPagesAfterCurrentPage = (int)Math.Ceiling((decimal)maxPages / (decimal)2) - 1;
if (currentPage <= maxPagesBeforeCurrentPage)
{
// current page near the start
startPage = 1;
endPage = maxPages;
}
else if (currentPage + maxPagesAfterCurrentPage >= totalPages)
{
// current page near the end
startPage = totalPages - maxPages + 1;
endPage = totalPages;
}
else
{
// current page somewhere in the middle
startPage = currentPage - maxPagesBeforeCurrentPage;
endPage = currentPage + maxPagesAfterCurrentPage;
}
}
// calculate start and end item indexes
var startIndex = (currentPage - 1) * pageSize;
var endIndex = Math.Min(startIndex + pageSize - 1, totalItems - 1);
// create an array of pages that can be looped over
var pages = Enumerable.Range(startPage, (endPage + 1) - startPage);
// update object instance with all pager properties required by the view
TotalItems = totalItems;
CurrentPage = currentPage;
PageSize = pageSize;
TotalPages = totalPages;
StartPage = startPage;
EndPage = endPage;
StartIndex = startIndex;
EndIndex = endIndex;
Pages = pages;
}
public int TotalItems { get; private set; }
public int CurrentPage { get; private set; }
public int PageSize { get; private set; }
public int TotalPages { get; private set; }
public int StartPage { get; private set; }
public int EndPage { get; private set; }
public int StartIndex { get; private set; }
public int EndIndex { get; private set; }
public IEnumerable<int> Pages { get; private set; }
}
}
Need Some C# Help?
Search fiverr for freelance C# developers.
Follow me for updates
When I'm not coding...
Me and Tina are on a motorcycle adventure around Australia.
Come along for the ride!