12/29/2022 5:51:54 PM

If you return paginated results from a database (or other data source), you will probably want to give the user an easy way to navigate through the results. This control will put links to pages based on your current page, records per page, and total records.

//Pager.cshtml.cs //This is the code for a test page accepting the requests. Note the "CurrentPage" property. using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; namespace TestApp.Web02.Pages { public class PagerModel : PageModel { //dont use "page" as the parameter, .NET doesn't like it [BindProperty(Name = "P", SupportsGet = true)] public int CurrentPage { get; set; } public void OnGet() { } } }

Pager.cshtml

Simple page using the Pager control

@page @model TestApp.Web02.Pages.PagerModel @{ var pager_model = new TestApp.Web02.Models.Pager() { RecordsPerPage = 25, CurrentPage = this.Model.CurrentPage, TotalRecords = 1200 }; } <h1>Pager</h1> <partial name="_Pager" model="pager_model" />
//Pager.cs //A model representing the pagination data (CurrentPage, RecordsPerPage, TotalRecords, TotalNumberOfPages) using System; namespace TestApp.Web02.Models { public class Pager { public int RecordsPerPage { get; set; } = 10; public int TotalRecords { get; set; } int _CurrentPage { get; set; } = 1; public int CurrentPage { get { return this._CurrentPage > 0 ? this._CurrentPage : 1; } set { this._CurrentPage = value; } } public int NumberOfPages { get { if (this.RecordsPerPage == 0) { return 1; } return (int)Math.Ceiling((decimal)this.TotalRecords / (decimal)this.RecordsPerPage); } } } }

AND FINALLY..._Pager.cshtml (in the "Shared" folder)

This is the Pager control.

@model TestApp.Web02.Models.Pager @{ //page_paramenter is the query paramter to pass the CurrentPage value //this value must match the value in the Pager.cshtml.cs file //dont use "page" as the parameter, .NET doesn't like it var page_paramenter = "p"; //what is the base url for this request var base_url = Context.Request.Path.Value; //add query strings, ignore the page_paramenter query string if it is present int query_strings_counter = 0; if (Context.Request.Query.Count > 0) { foreach (var query in Context.Request.Query) { if (query.Key != page_paramenter) { query_strings_counter++; if (query_strings_counter == 1) { base_url += "?"; } base_url += query.Key + "=" + query.Value; } } } //finish setting the base url with everything but the final page_paramenter int value if (query_strings_counter == 0) { base_url += "?"; } else { base_url += "&"; } base_url += page_paramenter + "="; } @if (this.Model.NumberOfPages > 1) { //how many links do we want to show (cant show all page links) decimal number_of_page_links_to_show = 10; //blocks of links to show: ex: 1,2,...10 is one block | 11,12,...20 is the next block | what block should we show //for this example, if current page is 1...10, block is 1, if current page is 11...20, the block is 2 decimal paging_block = Math.Ceiling((this.Model.CurrentPage) / number_of_page_links_to_show); //what page to start with var page_index_start = (paging_block * number_of_page_links_to_show) - number_of_page_links_to_show + 1; //what page to end with var page_index_end = page_index_start + number_of_page_links_to_show - 1; //dont go past number of pages if (page_index_end > this.Model.NumberOfPages) { page_index_end = this.Model.NumberOfPages; } //ui will also include the << to go to the beginning and >> to go the end //ui will include < to go back one block of pages, > to go forward a block of pages <div class="pager"> <a href="@(base_url + "1")">&lt;&lt;</a> @if (page_index_start > 1) { //go back a page block <a href="@(base_url + (page_index_start - 1).ToString())">&lt;</a> } @for (int page_index = (int)page_index_start; page_index <= page_index_end; page_index++) { var url = base_url + page_index; <a href="@url" class="@(this.Model.CurrentPage == page_index ? "selected" : "")">@page_index</a> } @if (page_index_end < this.Model.NumberOfPages) { //go forward a page block <a href="@(base_url + (page_index_end + 1).ToString())">&gt;</a> } <a href="@(base_url + this.Model.NumberOfPages.ToString())">&gt;&gt;</a> </div> } <style> a.selected { font-weight: bold; font-size: 2rem; } </style>