学习ASP.NET Core Razor 编程系列十九——分页
学习ASP.NET Core Razor 编程系列目录
学习ASP.NET Core Razor 编程系列二——添加一个实体
学习ASP.NET Core Razor 编程系列三——创建数据表及创建项目基本页面
学习ASP.NET Core Razor 编程系列四——Asp.Net Core Razor列表模板页面
学习ASP.NET Core Razor 编程系列五——Asp.Net Core Razor新建模板页面
学习ASP.NET Core Razor 编程系列六——数据库初始化
学习ASP.NET Core Razor 编程系列七——修改列表页面
学习ASP.NET Core Razor 编程系列八——并发处理
学习ASP.NET Core Razor 编程系列九——增加查询功能
学习ASP.NET Core Razor 编程系列十——添加新字段
学习ASP.NET Core Razor 编程系列十一——把新字段更新到数据库
学习ASP.NET Core Razor 编程系列十二——在页面中增加校验
学习ASP.NET Core Razor 编程系列十三——文件上传功能(一)
学习ASP.NET Core Razor 编程系列十四——文件上传功能(二)
学习ASP.NET Core Razor 编程系列十五——文件上传功能(三)
学习ASP.NET Core Razor 编程系列十六——排序
学习ASP.NET Core Razor 编程系列十七——分组
学习ASP.NET Core Razor 编程系列十八——并发解决方案
通过前面的教程学习,你可以实现一个简单的书籍管理系统。 在本教程将向书籍索引页中添加分页功能。
一、向书籍列表页添加分页功能
为了向书籍列表页添加分页功能,你需要安装X.PagedList.Core.Mvc
首先,我们需要安装分页组件包,在Visual Studio 2017中点击【项目】-【管理NuGet程序包】,打开NuGet包管理器窗体。 
其次,在NuGet包管理器窗体中,选择“浏览”标签,然后搜索X.PagedList,如下图所示。点击“安装”按钮安装X.PagedList.Core.Mvc的最新版本(本文中安装的版本为7.5.0)。 
第三, Nuget会下载X.PagedList.Mvc.Core包,并会弹出一个“更改”对话框,点击“确定”按钮。 
第四,在把PagedList.Mvc安装完成之后,PagedList包也被安装上了。如下图。 
把PagedList.Mvc安装完成之后,第一件事就是对OnGetAsync方法做更多的修改并将分页按钮添加到Index视图中。 如下图所示添加了分页按钮的书籍列表页。

二、向书籍列表后台代码添加分页功能
在Pages/Books/Index.cshtml.cs中,用以下代码替换。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using RazorMvcBooks.Models;
using Microsoft.AspNetCore.Mvc.Rendering;
using X.PagedList; namespace RazorMvcBooks.Pages.Books
{
public class IndexModel : PageModel
{
private readonly RazorMvcBooks.Models.BookContext _context; public IndexModel(RazorMvcBooks.Models.BookContext context)
{
_context = context;
} public List<Book> Books;
public SelectList Publishs;
public string Publish { get; set; }
public string NameSort { get; set; }
public string DateSort { get; set; }
public string CurrentFilter { get; set; }
public string CurrentSort { get; set; } public X.PagedList.IPagedList<Book> Book { get;set; } public async Task OnGetAsync(string publish, string searchString,string sortOrder,int? pageIndex)
{ ViewData["CurrentSort"] = sortOrder;
Publish = publish;
int pageSize = ;
ViewData["SearchString"] = searchString;
var page = pageIndex ?? ; //查询
IQueryable<string> PublishingQuery = from m in _context.Book
orderby m.Publishing
select m.Publishing; var books = from m in _context.Book
select m; if (!String.IsNullOrEmpty(searchString))
{
books = books.Where(s => s.Name.Contains(searchString));
} if (!String.IsNullOrEmpty(publish))
{
books = books.Where(x => x.Publishing == publish);
}
Publishs = new SelectList(await PublishingQuery.Distinct().ToListAsync()); //排序
NameSort = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
DateSort = sortOrder == "Date" ? "date_desc" : "Date"; ViewData["NameSortParm"] = NameSort;
ViewData["DateSortParm"] = DateSort; switch (sortOrder)
{ case "name_desc":
books = books.OrderByDescending(s => s.Name);
break; case "Date":
books = books.OrderBy(s => s.ReleaseDate);
break; case "date_desc":
books = books.OrderByDescending(s => s.ReleaseDate); break; default:
books = books.OrderBy(s => s.Name);
break; } Book = await books.AsNoTracking().ToPagedListAsync(page, pageSize);
//将分页结果放入ViewData供View使用
ViewData["books"] = Book; }
}
}
代码中将总页数参数、 当前的排序顺序参数和当前的筛选器参数添加到方法签名中。
public async Task OnGetAsync(string publish, string searchString,string sortOrder,int? pageIndex)
第一次显示页面,或如果用户未单击分页或排序链接,则所有参数都为null。 如果单击分页链接,页面变量将包含要显示的页码。
名为 CurrentSort 的ViewData元素提供了当前已排序的试图,因为这必须包含在分页链接中以保持排序顺序在分页时相同。
名为 searchString的ViewData元素提供了当前已筛选的视图。为了在分页过程中维护筛选规则以及在页面重新显示的时候把筛选值恢复到文本框中,该值一定要被包含进分页链接里
如果分页期间更改搜索字符串,显示的页会被重置为 1,因为新的筛选器可能会导致显示不同的数据。 在文本框中输入了值以及按下提交按钮搜索字符串就会改变。 在这种情况下,searchString参数不为 null。
在OnGetAsync方法的结尾,ToPagedListAsync方法将书籍查询结果转换为支持分页的集合类型,集合中包含了刚好能放进单页的书籍实体。 然后将这个单页大小的书籍集合 传递给视图。
Book = await books.AsNoTracking().ToPagedListAsync(page, pageSize);
代码中的ToPagedListAsync方法获得页面数和当前页码,并对IQueryable执行语句。 当IQueryable调用ToPagedListAsync时,该方法将返回只包含在请求页里的书籍列表。 属性HasPreviousPage和HasNextPage可用来启用或禁用Previous和Next分页按钮。
Book属性我们变更为
public X.PagedList.IPagedList<Book> Book { get;set; }
三、向书籍列表视图添加分页链接
在Pages/Books/Index.cshtml中,用以下代码替换现有代码。 高亮代码为更改的代码。
@page
@model RazorMvcBooks.Pages.Books.IndexModel
@using X.PagedList.Mvc.Core;
@using X.PagedList.Mvc.Common;
@using X.PagedList;
<!--// 7.6及以上版本需要引入Common命名空间,以支持PagedListRenderOptions .7.5以下的版本则不需要。--> @{
ViewData["Title"] = "Index";
} <h2>Index</h2>
<p>
<a asp-page="Create">Create New</a>
</p> <form>
<p>
<select asp-for="Publish" asp-items="Model.Publishs">
<option value="">All</option>
</select>
书籍名称
<input type="text" name="SearchString">
<input type="submit" value="查询" />
</p>
</form> <table class="table">
<thead>
<tr>
<th>
<a asp-page="./Index" asp-route-sortOrder="@Model.NameSort">
@Html.DisplayNameFor(model => model.Book[0].Name)
</a> </th>
<th>
<a asp-page="./Index" asp-route-sortOrder="@Model.DateSort">
@Html.DisplayNameFor(model => model.Book[0].ReleaseDate)
</a> </th>
<th>
@Html.DisplayNameFor(model => model.Book[0].Author)
</th>
<th>
@Html.DisplayNameFor(model => model.Book[0].Price)
</th>
<th>
@Html.DisplayNameFor(model => model.Book[0].Publishing)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model.Book)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.ReleaseDate)
</td>
<td>
@Html.DisplayFor(modelItem => item.Author)
</td>
<td>
@Html.DisplayFor(modelItem => item.Price)
</td>
<td>
@Html.DisplayFor(modelItem => item.Publishing)
</td>
<td>
<a asp-page="./Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-page="./Details" asp-route-id="@item.ID">Details</a> |
<a asp-page="./Delete" asp-route-id="@item.ID">Delete</a>
</td>
</tr>
} </tbody>
<tfoot>
<tr>
<td class="text-muted" colspan="4">
每页 @Model.Book.PageSize 条记录,本页有 @Model.Book.Count 条记录,共有 @Model.Book.TotalItemCount 条记录。
第 @(Model.Book.PageCount < Model.Book.PageNumber ? 0 : Model.Book.PageNumber) 页,共 @Model.Book.PageCount 页。
@*这个条件表达式的目的是防止出现 记录为0的情况,会出现 总页数为0,而当前是第1页的情况。*@ </td>
</tr>
</tfoot>
</table> @{ var prevDisabled = !Model.Book.HasPreviousPage ? "disabled" : "";
var nextDisabled = !Model.Book.HasNextPage ? "disabled" : "";
} <a asp-action="./Index"
asp-route-publish="@Model.Publish"
asp-route-sortOrder="@ViewData["CurrentSort"]"
asp-route-pageIndex="@(Model.Book.PageNumber - 1)"
asp-route-searchString="@ViewData["SearchString"]"
class="btn btn-default @prevDisabled">
上一页
</a> <a asp-action="./Index"
asp-route-publish="@Model.Publish"
asp-route-sortOrder="@ViewData["CurrentSort"]"
asp-route-pageIndex="@(Model.Book.PageNumber + 1)"
asp-route-searchString="@ViewData["SearchString"]"
class="btn btn-default @nextDisabled">
下一页
</a>
其中通过标记帮助程序显示分页按钮:
<a asp-action="./Index"
asp-route-publish="@Model.Publish"
asp-route-sortOrder="@ViewData["CurrentSort"]"
asp-route-pageIndex="@(Model.Book.PageNumber - 1)"
asp-route-searchString="@ViewData["SearchString"]"
class="btn btn-default @prevDisabled">
上一页
</a>
我们在Visual Studio 2017中按F5运行应用,并在浏览器中浏览书籍列表页。如下图。

在浏览器中单击以确保分页工作原理的不同的排序顺序中的分页链接。 然后输入搜索字符串,然后重试以验证分页还适用正确使用排序和筛选的分页。
四、向书籍列表视图添加分页链接
虽然上面我们实现了分页功能,但是一般分页,需要有页面显示,如下图。
如何实现上图中的分页样式呢?在Pages/Books/Index.cshtml中把书籍列表视图中“</table>”后面的代码,用以下代码替换,就可以实现。
@Html.PagedListPager(Model.Book, pageIndex => Url.Action("Index", new { pageIndex, sortOrder = ViewData["CurrentSort"],
searchString = ViewData["SearchString"], pageSize = ViewData["PageSize"] }),
new PagedListRenderOptions { LinkToFirstPageFormat = "首页", LinkToNextPageFormat = "下一页", LinkToPreviousPageFormat = "上一页",
LinkToLastPageFormat = "末页", MaximumPageNumbersToDisplay = 5, DisplayItemSliceAndTotal = false })
我们在Visual Studio 2017中按F5运行应用,并在浏览器中浏览书籍列表页。使用鼠标单击页码“4”,我们可以验证分页功能的正确使用。如下图。

学习ASP.NET Core Razor 编程系列十九——分页的更多相关文章
- 学习ASP.NET Core Razor 编程系列十八——并发解决方案
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- 学习ASP.NET Core Razor 编程系列十六——排序
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- 学习ASP.NET Core Razor 编程系列十五——文件上传功能(三)
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- 学习ASP.NET Core Razor 编程系列十四——文件上传功能(二)
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- 学习ASP.NET Core Razor 编程系列十二——在页面中增加校验
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- 学习ASP.NET Core Razor 编程系列十——添加新字段
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- 学习ASP.NET Core Razor 编程系列十七——分组
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- 学习ASP.NET Core Razor 编程系列十三——文件上传功能(一)
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
- 学习ASP.NET Core Razor 编程系列十一——把新字段更新到数据库
学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...
随机推荐
- MYSQL———正则表达式查询!
在使用select查询的过程中,有时会用到正则表达式对结果进行查询,将学习到的内容进行总结! 一 语法结构如下: 二 常用匹配方式进行示例说明 首先创建表student,表的结构如下: 1·^:查询s ...
- 基于Java实现红黑树的基本操作
首先,在阅读文章之前,我希望读者对二叉树有一定的了解,因为红黑树的本质就是一颗二叉树.所以本篇博客中不在将二叉树的增删查的基本操作了,需要了解的同学可以到我之前写的一篇关于二叉树基本操作的博客:htt ...
- TensorFlow之DNN(三):神经网络的正则化方法(Dropout、L2正则化、早停和数据增强)
这一篇博客整理用TensorFlow实现神经网络正则化的内容. 深层神经网络往往具有数十万乃至数百万的参数,可以进行非常复杂的特征变换,具有强大的学习能力,因此容易在训练集上过拟合.缓解神经网络的过拟 ...
- 分布式团队中沟通引发的问题, itest 解决之道
导读: 从问题场景和 itest 优雅解决办法及示例2部分来阐述 1.问题场景: 研发团队是分散在几地的分布式团队,经常会因沟通引来一些问题.如下三图是开发觉得测试进度太慢,一番对话之后, 接下来他们 ...
- 频率学派与贝叶斯学派(先验分布与后验分布,MLE和MAP)
频率学派(古典学派)和贝叶斯学派是数理统计领域的两大流派. 这两大流派对世界的认知有本质的不同:频率学派认为世界是确定的,有一个本体,这个本体的真值是不变的,我们的目标就是要找到这个真值或真值所在的范 ...
- 【EXCEL-折线图】百折不挠 | 用EXCEL画出与众不同的折线图(曲线图)
很多熟悉EXLCE的朋友都知道EXCEL在生成统计图表方面的强大功能,我们在写各类总结.报告.方案等文档时常涉及到各类统计数字,将统计数字用图表的形式展示出来,既直观又美观.下面我分享一种不一样的折线 ...
- 【重学计算机】操作系统D2章:处理器管理
1. 指令与处理器模式 指令执行周期:取指.译码.执行 指令分类(根据权限) 特权指令:只能被操作系统内核使用(启动IO,置PC值) 非特权指令:所有程序都能使用 处理器模式: 共有四种:0内核模式, ...
- asp.net core系列 54 IS4用客户端凭据保护API
一. 概述 本篇开始进入IS4实战学习,从第一个示例开始,该示例是 “使用客户端凭据保护API”,这是使用IdentityServer保护api的最基本场景.该示例涉及到三个项目包括:Identity ...
- Java面试前需要了解的东西
一.前言 只有光头才能变强 回顾前面: 广州三本找Java实习经历 上一篇写了自己面试的经历和一些在面试的时候遇到的题目(笔试题和面试题). 我在面试前针对Java基础也花了不少的时间,期间也将自己写 ...
- Asp.NetCore轻松学-使用Docker进行容器化托管
前言 没有 docker 部署的程序是不完整的,在写了 IIS/Centos/Supervisor 3篇托管介绍文章后,终于来到了容器化部署,博客园里面有关于 docker 部署的文章比比皆是,作为硬 ...