ASP.NET Core MVC Pagination Using A Tag Helper

As I progress through migrating this site from ASP.NET 4.6.x to ASP.NET Core, there are some packages that I used in the former that no longer suit my needs in the latter. One of these packages included a class library and HtmlHelper that could be used in conjunction to generate pagination markup and data.

In addition to this package not being supported in ASP.NET Core MVC, it also has a few constructs that did not meet my needs moving forward. That being said, I decided it best I produce my own solution and share it with the community.

Pioneer Pagination

An example of Pioneer Pagination Tag Helper output.
Pagination is used in some form in almost every web application to divide returned data and display it on multiple pages. Pagination also includes the logic of preparing and displaying the links to the various pages. https://en.wikipedia.org/wiki/Pagination

Pagination itself is a three step story.

  1. Acquisition of data.
  2. Generation of metadata to support the generation of markup.
  3. Generating markup based on metadata.

Acquiring Data

Gathering a "page" of data is a distinct operation in itself. It should be treated independently of any desired destination and because of such, Pioneer Pagination makes no effort nor has a desire to couple step 1 with steps 2 and 3. Instead, it leaves that option up to the user as opposed to assuming what the user wants.

One such example on how to acquire paged data, which I use for this blog, is to implement paging in Entity Framework. More specifically two Entity Framework extension methods, Skip and Take.

public IEnumerable<PostEntity> GetAllPaged(int count, int page = 1)
{
    return _blogContext
            .Posts
            .Where(x => x.Published)
            .OrderByDescending(x => x.PostedOn)
            .Skip((page - 1) * count)
            .Take(count)
            .ToList();
}

A request to this method will ask Entity Framework to get a collection of pages by skipping (Skip) x and taking (Take) y. The count parameter signifies the total number of posts you want to Take and the page parameter represents a number of pages you want to Skip.

Metadata

In order to generate markup that will visually represent our paginated list, we must produce metadata that represents our desired state. Pioneer Pagination handles this in the form of a service call.

public ActionResult Index(int page = 1)
{
    // Typically obtained from a service/repository
    var totalNumberInCollection = 100;
	// Typically obtained from configuration
    var itemsPerPage = 5;
    ViewBag.PaginatedMeta = _paginatedMetaService.GetMetaData(totalNumberInCollection, page, itemsPerPage);
    return View("Blog", post);
}

This data is bound to a controllers ViewBag as a means of supplying our Tag Helper the information it needs to work its magic.

Tag Helper

Tag Helpers enable server-side code to participate in creating and rendering HTML elements in Razor files. https://docs.asp.net/en/latest/mvc/views/tag-helpers/intro.html

Now that we have a "page" of data to display, we need to use that information in conjunction our metadata to produce a paginated list.

<pioneer-pagination info="@ViewBag.PaginatedMeta" route="/blog"></pioneer-pagination>

Where Do I Get It?

For the most up-to-date look into how to use Pioneer Pagination, be sure to visit the Pioneer Pagination GitHub repository. If you would like to start using it today, it is available as a NuGet Package for public consumption.

If you have any requests or ideas for improvements, please feel free to share them with me over at GitHub or in the comments located below.