C# pagination example with working code.

One thing nearly all websites require is some way of paging through either the blogs or items that they sell.

This is done via pagination and this blog will show you how to do this with a working example in C# .NET MVC that can be downloaded from GitHub.

To use pagination in ASP .NET I use a partial view for the pagination code and a view to show the results. I also have a helper class and controller.

So let's get started, below is the code for the search page.

HTML Page.

@model  Web.Controller.Helpers.DisplayPagerViewModel
@{
    string query = Request.QueryString["q"];
    string appendS = Model.DisplaySearchResults.Count() != 1 ? "s" : null;
}

}
<div class="container">
    <div class="row">
        <div clas="col-12">
            <h2>Pagination Example</h2>
            <p>Enter either beer, cider or soft drink</p>
            @using (Html.BeginForm("SearchResults", "Pager", FormMethod.Get, new { enctype = "multipart/form-data" }))
            {
                <div>
                    @Html.TextBox("q", "") <br />

                    <input type="submit" value="Search" />
                </div>
            }
        </div>

    </div>
</div>
<div class="container">
    @{
        if (Model.DisplaySearchResults.Any())
        {
            <p class="text-info mt-3">@Html.Raw($"Your search for <strong>{query}</strong> returned <strong>{Model.NumberOfResults} result{appendS}</strong>")</p>
            
            <ul class="list-unstyled">
                @foreach (var result in Model.DisplaySearchResults)
                {
                    <li>
                        @result.Beverage - @result.Type
                    </li>
                }
            </ul>
        }
        else
        {
            <p class="text-danger">@Html.Raw($"Sorry no results found for <strong>{query}</strong>")</p>
        }

    }

</div>

@Html.Partial("~/Views/Partials/pvPager.cshtml")

Code for partial view pager.

Below is the code for the pager within the partial view in ASP.NET MVC, as you can see it's pretty simple and uses a for loop to create the links for the pages.

@model  Web.Controller.Helpers.DisplayPagerViewModel

@{
    string query = Request.QueryString["q"];
    var currentPage = Model.Pager.CurrentPage;


    if (currentPage == 0)
    {
        currentPage = 1;
    }
}

@if (Model.Pager.EndPage > 1)
{
    <div class="container">
        <nav aria-label="Page navigation">
            <p class="text-info mt-3">Page @currentPage of @Model.Pager.TotalPages</p>
            <ul class="pagination">
                @for (var page = Model.Pager.StartPage; page <= Model.Pager.EndPage; page++)
                {
                    <li class="page-item @(page == Model.Pager.CurrentPage ? "active" : "")">
                        @if (!string.IsNullOrEmpty(query))
                        {
                            <a class="page-link" href="?q=@query&&page=@page">@page</a>
                        }
                        else
                        {
                            <a class="page-link" href="?page=@page">@page</a>
                        }

                    </li>
                }
            </ul>
        </nav>
    </div>
}

Helper Class.

The helper class has the data to show hard-coded, but in reality, this data would come from a database or some other source.

It also contains the pagination code and some helper classes. In a production site, these classes would be either in separate class libraries or classes.  

using System;
using System.Collections.Generic;

namespace Web.Controller.Helpers
{
    public static class ListOfBeverages
    {
        public static List TopAlcoholicDrinksUk()
        {
            List lstBeers = new List
            {
                new ListBeveragesViewModel("Peroni", "beer"),
                new ListBeveragesViewModel("Guinness", "beer"),
                new ListBeveragesViewModel("Bulmers", "cider"),
                new ListBeveragesViewModel("Stella Artois", "beer"),
                new ListBeveragesViewModel("Magners", "cider"),
                new ListBeveragesViewModel("Heineken", "beer"),
                new ListBeveragesViewModel("Amstel", "beer"),
                new ListBeveragesViewModel("Corona", "beer"),
                new ListBeveragesViewModel("Becks", "beer"),
                new ListBeveragesViewModel("Budweiser", "beer"),
                new ListBeveragesViewModel("Kopparberg", "cider"),
                new ListBeveragesViewModel("San Miguel", "beer"),
                new ListBeveragesViewModel("Tetley's Brewery", "beer"),
                new ListBeveragesViewModel("Kronenburg 1664", "beer"),
                new ListBeveragesViewModel("Strongbow", "cider"),
                new ListBeveragesViewModel("Carlsberg", "beer"),
                new ListBeveragesViewModel("Hobgoblin", "cider"),
                new ListBeveragesViewModel("Sol", "beer"),
                new ListBeveragesViewModel("Thatchers Gold", "cider"),
                new ListBeveragesViewModel("Pepsi Max", "soft drink")
            };


            return lstBeers;

        }
    }

    public class DisplayPagerViewModel
    {
        public IEnumerable DisplaySearchResults { get; set; }
        public PagerHelper.Pagination Pager                             { get; set; }
        public int NumberOfResults                                      { get; set; }
    }

    public class ListBeveragesViewModel
    {
        public ListBeveragesViewModel(string beverage, string type)
        {
            Beverage    = beverage;
            Type        = type;
        }

        public string Beverage { get; set; }
        public string Type { get; set; }
    }
    public static class PagerHelper
    {

        public class Pagination
        {
            public Pagination(int totalItems, int? page, int pageSize = 10)
            {
                var totalPages = (int)Math.Ceiling(totalItems / (decimal)pageSize);

                if (page > totalPages || page < 0)
                {
                    page = 1;
                }
                var currentPage     = 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;
                    }
                }

                StartPage       = startPage;
                CurrentPage     = currentPage;
                PageSize        = pageSize;
                TotalItems      = totalItems;
                TotalPages      = totalPages;
                EndPage         = endPage;
            }

            public int StartPage        { get; }
            public int CurrentPage      { get; }
            public int PageSize         { get; }
            public int TotalItems       { get; }
            public int TotalPages       { get; }
            public int EndPage          { get; }
        }
    }
}
Controller.

Finally, I have the controller which returns the views, as you can see in the SearchResults ActionResult I use a foreach loop to iterate over the data with a where clause to return only the data that matches the query, then the results get added to the model and returned to the view.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Web.Controller.Helpers;

namespace Web.Controller.Controllers
{
    public class PagerController : System.Web.Mvc.Controller
    {
        [HttpGet]
        public ActionResult Home()
        {
            return View();
        }

        [HttpGet]
        public ActionResult SearchResults(string q, int? page = 0)
        {
            if (string.IsNullOrEmpty(q))
            {
                q = "";
            }
            List model = new List();

            var beverages = ListOfBeverages.TopAlcoholicDrinksUk();

            foreach (var beverage in beverages.Where(x=>string.Equals(x.Type, q, StringComparison.CurrentCultureIgnoreCase)))
            {
                string beverageName = beverage.Beverage;
                string beverageType = beverage.Type;

                model.Add(new ListBeveragesViewModel(beverageName,beverageType));
            }

            int totalNumberOfRecords = model.Count;

            int numberOfRecordsPerPage = 5;
            var numberOfRecordsToDisplay = new PagerHelper.Pagination(totalNumberOfRecords, page, numberOfRecordsPerPage);

            var displayResults = new DisplayPagerViewModel
            {
                DisplaySearchResults    = model.Skip((numberOfRecordsToDisplay.CurrentPage - 1)* numberOfRecordsToDisplay.PageSize).Take(numberOfRecordsToDisplay.PageSize).ToList(),
                Pager                   = numberOfRecordsToDisplay,
                NumberOfResults         = model.Count
            };
            return View("~/Views/Pager/SearchResults.cshtml",displayResults);
        }
    }
}
Summary C# pagination example.

The results of all the code above can be seen in the image below.

C# pagination example with working code

Thank you for reading this blog and I hope you found it helpful, don't forget you can download the code from GitHub which contains the working example.