Pagination is a crucial feature for any web application that deals with large amounts of data. It allows users to navigate through data easily without overwhelming them with too much information at once. In this post, we will explore how to implement pagination in a .NET Core MVC application using Controllers and Razor Pages. We will use a simple example to demonstrate the process.
Prerequisites
- .NET Core SDK installed
- Basic knowledge of ASP.NET Core MVC
- Visual Studio or any preferred IDE
Step 1: Create a New ASP.NET Core MVC Project
First, create a new ASP.NET Core MVC project. Open your terminal or command prompt and run the following command:
dotnet new mvc -n PaginationExample cd PaginationExample
Open the project in your preferred IDE.
Step 2: Set Up Your Data Model
For this example, we will use a simple data model. Let’s create a Product
class in the Models
folder:
public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } }
Step 3: Create a Database Context
Set up Entity Framework Core to handle our data operations. Add a new class called AppDbContext
in the Data
folder:
using Microsoft.EntityFrameworkCore; public class AppDbContext : DbContext { public DbSet<Product> Products { get; set; } public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { } }
Register AppDbContext
in Startup.cs
:
public void ConfigureServices(IServiceCollection services) { services.AddDbContext<AppDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddControllersWithViews(); }
Don’t forget to add your connection string in appsettings.json
:
"ConnectionStrings": { "DefaultConnection": "Your_Connection_String_Here" }
Step 4: Create a Controller
Create a ProductsController
to handle product-related operations:
using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using PaginationExample.Data; using PaginationExample.Models; using System.Linq; using System.Threading.Tasks; public class ProductsController : Controller { private readonly AppDbContext _context; public ProductsController(AppDbContext context) { _context = context; } public async Task<IActionResult> Index(int pageNumber = 1, int pageSize = 10) { var products = await PaginatedList<Product>.CreateAsync(_context.Products.AsNoTracking(), pageNumber, pageSize); return View(products); } }
Step 5: Implement PaginatedList Helper Class
Create a helper class PaginatedList<T>
to handle pagination logic. Add a new class file PaginatedList.cs
in the Models
folder:
using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; public class PaginatedList<T> : List<T> { public int PageIndex { get; private set; } public int TotalPages { get; private set; } public PaginatedList(List<T> items, int count, int pageIndex, int pageSize) { PageIndex = pageIndex; TotalPages = (int)Math.Ceiling(count / (double)pageSize); this.AddRange(items); } public bool HasPreviousPage { get { return PageIndex > 1; } } public bool HasNextPage { get { return PageIndex < TotalPages; } } public static async Task<PaginatedList<T>> CreateAsync(IQueryable<T> source, int pageIndex, int pageSize) { var count = await source.CountAsync(); var items = await source.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToListAsync(); return new PaginatedList<T>(items, count, pageIndex, pageSize); } }
Step 6: Create Razor View for Displaying Products
Create a Razor view Index.cshtml
under the Views/Products
folder:
@model PaginatedList<Product> @{ ViewData["Title"] = "Products"; } <h1>Products</h1> <table class="table"> <thead> <tr> <th> @Html.DisplayNameFor(model => model.First().Name) </th> <th> @Html.DisplayNameFor(model => model.First().Price) </th> </tr> </thead> <tbody> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Name) </td> <td> @Html.DisplayFor(modelItem => item.Price) </td> </tr> } </tbody> </table> <div class="pagination"> @if (Model.HasPreviousPage) { <a asp-action="Index" asp-route-pageNumber="@(Model.PageIndex - 1)" asp-route-pageSize="@ViewData["pageSize"]">Previous</a> } @for (int i = 1; i <= Model.TotalPages; i++) { <a asp-action="Index" asp-route-pageNumber="@i" asp-route-pageSize="@ViewData["pageSize"]" class="@(i == Model.PageIndex ? "selected" : "")">@i</a> } @if (Model.HasNextPage) { <a asp-action="Index" asp-route-pageNumber="@(Model.PageIndex + 1)" asp-route-pageSize="@ViewData["pageSize"]">Next</a> } </div>
Step 7: Seed Data (Optional)
To see pagination in action, you might want to seed some data. Add the following code to your Startup.cs
file:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, AppDbContext context) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); // Seed data if (!context.Products.Any()) { var products = new List<Product>(); for (int i = 1; i <= 100; i++) { products.Add(new Product { Name = "Product " + i, Price = i }); } context.Products.AddRange(products); context.SaveChanges(); } } else { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); }); }
Conclusion
You have successfully implemented pagination in a .NET Core MVC application using Controllers and Razor Pages. This approach ensures that your application handles large datasets efficiently, improving the user experience. You can further customize the pagination logic and the user interface to fit your application’s requirements. Happy coding!