ASP.NET MVC - Pagination Example with Logic like Google
Example built with ASP.NET MVC
Other versions available:
- Angular: Angular 10, 9, 8, 2/5, Angular + Node
- React: React, React + Node
- Vue: Vue, Vue + Node
- AngularJS: AngularJS
- ASP.NET: Razor Pages
This is an example of how to setup pagination logic similar to what you see in Google search results.
It's written in C# and ASP.NET MVC, but the pagination logic is pure C# and could easily be converted to other languages such as Javascript to run on NodeJS, PHP or Java etc. The front end pagination component in the example is styled using Bootstrap.
Here it is in action: (See on .NET Fiddle at https://dotnetfiddle.net/eOe3tv)
Google Pagination Logic
The logic in Google's pagination is as follows:
- there are 10 page links shown at any time (e.g. 1 2 3 4 5 6 7 8 9 10) unless there are less than 10 total pages
- the active link (current page) is in the 6th position, except for when the active link is below 6 or less than 4 from the last position
Here's what it looks like for each page if there are 15 total pages:
[1] 2 3 4 5 6 7 8 9 10
1 [2] 3 4 5 6 7 8 9 10
1 2 [3] 4 5 6 7 8 9 10
1 2 3 [4] 5 6 7 8 9 10
1 2 3 4 [5] 6 7 8 9 10
1 2 3 4 5 [6] 7 8 9 10
2 3 4 5 6 [7] 8 9 10 11
3 4 5 6 7 [8] 9 10 11 12
4 5 6 7 8 [9] 10 11 12 13
5 6 7 8 9 [10] 11 12 13 14
6 7 8 9 10 [11] 12 13 14 15
6 7 8 9 10 11 [12] 13 14 15
6 7 8 9 10 11 12 [13] 14 15
6 7 8 9 10 11 12 13 [14] 15
6 7 8 9 10 11 12 13 14 [15]
While this looks pretty simple at first there's actually a bit of tricky logic to get it working correctly, particularly when the selected page is below 6 or less than 4 from the end, and also to cater for when there are more or less than 10 total pages.
To make the pagination logic reusable across different pages and projects, I packaged it up in a C# class called Pager.cs:
Pager.cs - Pagination Logic in C# like Google
public class Pager
{
public Pager(int totalItems, int? page, int pageSize = 10)
{
// calculate total, start and end pages
var totalPages = (int)Math.Ceiling((decimal)totalItems / (decimal)pageSize);
var currentPage = page != null ? (int)page : 1;
var startPage = currentPage - 5;
var endPage = currentPage + 4;
if (startPage <= 0)
{
endPage -= (startPage - 1);
startPage = 1;
}
if (endPage > totalPages)
{
endPage = totalPages;
if (endPage > 10)
{
startPage = endPage - 9;
}
}
TotalItems = totalItems;
CurrentPage = currentPage;
PageSize = pageSize;
TotalPages = totalPages;
StartPage = startPage;
EndPage = endPage;
}
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; }
}
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!
More C# Posts
- .NET 7.0 + MySQL - Connect to MySQL Database with Dapper in C# and ASP.NET Core
- MySQL + Dapper - Create database if it doesn't exist on startup with C# and ASP.NET Core
- .NET 7.0 + Dapper + MySQL - CRUD API Tutorial in ASP.NET Core
- Postgres CRUD Operations in C# with Dapper Repository
- .NET 7.0 + C# - JWT Authentication Tutorial without ASP.NET Core Identity
- .NET 7.0 + Postgres - Connect to PostgreSQL Database with Dapper in C# and ASP.NET Core
- Postgres + Dapper - Create database if it doesn't exist on startup with C# and ASP.NET Core
- .NET 7.0 + Dapper + PostgreSQL - CRUD API Tutorial in ASP.NET Core
- SqlClient.SqlException - The certificate chain was issued by an authority that is not trusted
- .NET 7.0 + Dapper - Connect to MS SQL Server Database in ASP.NET Core
- .NET 7.0 + Dapper + MS SQL Server - CRUD API Tutorial in ASP.NET Core
- Dapper + SQL Server - Create database if it doesn't exist on startup in ASP.NET Core
- .NET 7.0 + Dapper - Connect to SQLite Database in ASP.NET Core
- .NET 7.0 + Dapper + SQLite - CRUD API Tutorial in ASP.NET Core
- C# + .NET 7.0 - Serialize (Convert) Enum to String in API Response
- .NET 7.0 + Dapper - Create Database Tables on Startup in ASP.NET Core
- C# + RestSharp - Add Bearer Token Authorization Header to HTTP Request in .NET
- C# + RestSharp - HTTP PUT Request Examples in .NET
- C# + RestSharp - HTTP DELETE Request Examples in .NET
- C# + RestSharp - HTTP GET Request Examples in .NET
- C# + RestSharp - POST a JSON Object to an API in .NET
- C# + RestSharp - HTTP POST Request Examples in .NET
- .NET 7.0 + RestSharp - Deserialize Dynamic JSON Response from HTTP Request
- .NET 7.0 - Create a Base Controller in .NET
- .NET 7.0 Auth - Sign & Validate JWT Without Core Identity
- .NET 7.0 - Create Custom AuthorizeAttribute and AllowAnonymous Attribute
- .NET 7.0 - Facebook Authentication API Tutorial with Example
- .NET 6.0 - Apply Authorize Attribute to All Controllers
- .NET 6.0 - Connect to InMemory Database with Entity Framework Core
- .NET 6.0 - Connect to SQLite Database with Entity Framework Core
- .NET 6.0 - Connect to PostgreSQL Database with Entity Framework Core
- .NET 6.0 - Connect to MySQL Database with Entity Framework Core
- .NET 6.0 - Connect to SQL Server with Entity Framework Core
- .NET 6.0 - CRUD API Example and Tutorial
- .NET 6.0 - Send an Email via SMTP with MailKit
- .NET 6.0 - Boilerplate API Tutorial with Email Sign Up, Verification, Authentication & Forgot Password
- .NET 6.0 - Role Based Authorization Tutorial with Example API
- .NET 6.0 - Minimal API Tutorial and Example
- .NET 6.0 - Execute EF Database Migrations from Code on Startup
- .NET 6.0 - Database Migrations to Different DB Per Environment (SQLite in Dev, SQL Server in Prod)
- .NET 6.0 - JWT Authentication with Refresh Tokens Tutorial with Example API
- .NET 6.0 - Create and Validate JWT Tokens + Use Custom JWT Middleware
- .NET 6.0 - Global Error Handler Tutorial with Example
- .NET 6.0 - Hash and Verify Passwords with BCrypt
- .NET 6.0 - User Registration and Login Tutorial with Example API
- .NET 6.0 - Basic Authentication Tutorial with Example API
- .NET 6.0 - JWT Authentication Tutorial with Example API
- .NET 5.0 - Connect to MySQL Database with Entity Framework Core
- .NET 5.0 - Connect to SQL Server with Entity Framework Core
- .NET - Return Enum as String from API
- .NET - Startup Class in a Nutshell
- .NET - Program Class and Main Method in a Nutshell
- .NET + MSBuild - C# Project File (.csproj) in a Nutshell
- .NET 5.0 - CRUD API Example and Tutorial
- .NET 5.0 - Send an Email via SMTP with MailKit
- .NET 5.0 - Boilerplate API with Email Sign Up, Verification, Authentication & Forgot Password
- .NET 5.0 - Role Based Authorization Tutorial with Example API
- .NET 5.0 - Bare Bones API Tutorial
- VS Code + .NET - Debug a .NET Web App in Visual Studio Code
- .NET 5.0 API - JWT Authentication with Refresh Tokens
- .NET 5.0 - Automatic Entity Framework Migrations to SQL Database on Startup
- .NET 5.0 - Entity Framework Migrations for Multiple Databases (SQLite and SQL Server)
- .NET 5.0 - Create and Validate JWT Tokens + Use Custom JWT Middleware
- .NET 5.0 - Global Error Handler Tutorial
- .NET 5.0 - Hash and Verify Passwords with BCrypt
- .NET 5.0 API - Allow CORS requests from any origin and with credentials
- .NET 5.0 - Simple API for Authentication, Registration and User Management
- .NET 5.0 - Basic Authentication Tutorial with Example API
- .NET 5.0 - JWT Authentication Tutorial with Example API
- .NET Core C# + AWS SES - Send Email via SMTP with AWS Simple Email Service
- Blazor WebAssembly - Fake Backend Example for Backendless Development
- Blazor WebAssembly - User Registration and Login Example & Tutorial
- ASP.NET Core 3.1 - Global Error Handler Tutorial
- Blazor WebAssembly - Authentication Without Identity
- Blazor WebAssembly - HTTP GET Request Examples
- Blazor WebAssembly - HTTP POST Request Examples
- Blazor WebAssembly - Display a list of items
- C# - Encode and Decode Base64 Strings
- Blazor WebAssembly - Basic HTTP Authentication Tutorial & Example
- Blazor WebAssembly - JWT Authentication Example & Tutorial
- Blazor WebAssembly - Get Query String Parameters with Navigation Manager
- Blazor WebAssembly - Form Validation Example
- ASP.NET Core Blazor WebAssembly - Communication Between Components
- ASP.NET Core 3.1 - Create and Validate JWT Tokens + Use Custom JWT Middleware
- ASP.NET Core 3.1 - Hash and Verify Passwords with BCrypt
- ASP.NET Core 3.1 - Send Emails via SMTP with MailKit
- ASP.NET Core 3.1 - Boilerplate API with Email Sign Up, Verification, Authentication & Forgot Password
- ASP.NET Core - Setup Development Environment
- ASP.NET Core 3.1 API - JWT Authentication with Refresh Tokens
- ASP.NET Core API - Allow CORS requests from any origin and with credentials
- ASP.NET Core - EF Core Migrations for Multiple Databases (SQLite and SQL Server)
- ASP.NET Core - Automatic EF Core Migrations to SQL Database on Startup
- ASP.NET Core 3.1 - Basic Authentication Tutorial with Example API
- ASP.NET Core 3.1 - Role Based Authorization Tutorial with Example API
- ASP.NET Core 3.1 - Simple API for Authentication, Registration and User Management
- ASP.NET Core 3.1 - JWT Authentication Tutorial with Example API
- ASP.NET Core 2.2 - Role Based Authorization Tutorial with Example API
- C# - Pure Pagination Logic in C# / ASP.NET
- ASP.NET Core Razor Pages - Pagination Example
- ASP.NET Core 2.2 - Basic Authentication Tutorial with Example API
- ASP.NET Core 2.2 - JWT Authentication Tutorial with Example API
- ASP.NET Core 2.2 - Simple API for Authentication, Registration and User Management
- C# / ASP.NET - Domain Validation Logic in Domain Driven Design (DDD)
- Fluent NHibernate - Unproxy Entity Objects with AutoMapper
- C# - Incremental Delay to Prevent Brute Force or Dictionary Attack
- Dynamic LINQ - Using strings to sort by properties and child object properties
- Web API 2 + ELMAH - Log ALL Unhandled Exceptions
- Moq - Get Setup() to return a dynamic collection from a fake repository
- Post a simple string value from AngularJS to .NET Web API
- ASP.NET Web API 2 - Enum Authorize Attribute
- ASP.NET MVC - Required Checkbox with Data Annotations
- C# - Get time zone and UTC offset from latitude and longitude (GPS coordinates)
- Using MVC 4 Web Api with jQuery DataTables
- MVC CheckboxList for property of type IList<Enum>
- MVC3 redirect to mobile site and stop executing
- ASP.NET MVC3 + Altairis Web Security Toolkit
- NHibernate - Map Umbraco member profile properties with Custom Interceptor
- Populate ASP.NET dropdown list with month names using LINQ