Asp.Net Bootstrap Pagination with Google "like" Logic

Pagination, like shown in the image above, has always been a little tricky. What's even trickier is getting it to behave like Google's pagination where the inner pages stay in the middle.

However with Bootstrap and a little logic, making great paginations are easier than ever!

I'll have to give credit where credit is due because I got the logic from Jason Watmore, particularly this blog: ASP.NET MVC - Pagination Example with Logic like Google. This article simply ports his Asp.Net MVC code to Webforms code. I hope you find it useful.

A working sample of this code is located here: Asp.Net Bootstrap Pagination Sample

Here is my code

A single Asp.Net Literal control renders the content and the code behind builds up the content from a StringBuilder object. The logic is derived from the Pager object.

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="pagination.aspx.cs" Inherits="web_programming_asp_net_articles_resources_pagination" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Asp.Net Bootstrap Pagination Sample</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
</head>
<body>
    <form id="form1" runat="server">
    <div class="container content">
        <h1>Asp.Net Bootstrap Pagination Sample</h1>

<asp:Literal ID="litContent" runat="server" EnableViewState="false" />

    </div>
    </form>
</body>
</html>
using System;
using System.Text;
using System.Collections.Generic;

public partial class web_programming_asp_net_articles_resources_pagination : System.Web.UI.Page
{
    Int32 iPage;
    Int32 iPageSize;

    protected override void OnInit(EventArgs e)
    {
        // Set Main Variables
        iPageSize = 10;

        // Grab the QueryString p Value
        if (!String.IsNullOrEmpty(Request.QueryString["p"]))
        {
            try { iPage = Convert.ToInt32(Request.QueryString["p"]); }
            catch { Response.Clear(); Response.Redirect("pagination.aspx"); }
            if (iPage < 1)
                iPage = 1;
        }
        else
            iPage = 1;

        base.OnInit(e);
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        Int32 iCounter = 0;
        List<string> l = new List<string>();

        // Create 350 Items and add it to the Generic List
        while (iCounter < 350)
        {
            l.Add("Item: " + (iCounter + 1).ToString());
            iCounter++;
        }

        // Create a Pager and Load the Variables
        Pager p = new Pager(l.Count, iPage, iPageSize);

        // Don't let them go past the last page
        if (iPage > p.TotalPages)
        {
            Response.Clear();
            Response.Redirect("pagination.aspx");
        }

        // Our StringBuilder
        StringBuilder objStr = new StringBuilder();
        objStr.AppendLine("<pre>");
        
        // Some Helpful Info for debugging
        objStr.Append("TotalItems: ");
        objStr.AppendLine(p.TotalItems.ToString());
        objStr.Append("CurrentPage: ");
        objStr.AppendLine(p.CurrentPage.ToString());
        objStr.Append("PageSize: ");
        objStr.AppendLine(p.PageSize.ToString());
        objStr.Append("TotalPages: ");
        objStr.AppendLine(p.TotalPages.ToString());
        objStr.Append("StartPage: ");
        objStr.AppendLine(p.StartPage.ToString());
        objStr.Append("EndPage: ");
        objStr.AppendLine(p.EndPage.ToString());
        objStr.AppendLine();

        // Item Display Logic
        for (Int32 i = ((iPage - 1) * iPageSize); i < (((iPage - 1) * iPageSize) + iPageSize); i++)
        {
            if (i >= l.Count)
                break;
            objStr.AppendLine(l[i]);
        }
        objStr.AppendLine("</pre>");

        // Paging Logic
        objStr.AppendLine("        <ul class=\"pagination\">");
        if (iPage > 1)
        {
            objStr.AppendLine("            <li><a href=\"pagination.aspx\">First</a></li>");

            objStr.Append("            <li><a href=\"pagination.aspx?p=");
            objStr.Append(iPage - 1);
            objStr.Append("\">Previous");
            objStr.AppendLine("</a></li>");
        }

        for (Int32 i = p.StartPage; i < p.EndPage + 1; i++)
        {
            if (i == iPage)
            {
                objStr.Append("            <li class=\"active\"><a href=\"pagination.aspx?p=");
                objStr.Append(i);
                objStr.Append("\">");
                objStr.Append(i);
                objStr.AppendLine("</a></li>");
            }
            else
            {
                objStr.Append("            <li><a href=\"pagination.aspx?p=");
                objStr.Append(i);
                objStr.Append("\">");
                objStr.Append(i);
                objStr.AppendLine("</a></li>");
            }
        }

        if (iPage < p.TotalPages)
        {
            objStr.Append("            <li><a href=\"pagination.aspx?p=");
            objStr.Append(iPage + 1);
            objStr.Append("\">Next");
            objStr.AppendLine("</a></li>");

            objStr.Append("            <li><a href=\"pagination.aspx?p=");
            objStr.Append(p.TotalPages);
            objStr.Append("\">Last");
            objStr.AppendLine("</a></li>");
        }

        objStr.AppendLine("        </ul>");

        litContent.Text = objStr.ToString();

    }
}
using System;
/// <summary>
/// Summary description for Pager
/// </summary>
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; }
}