ASP.NET MVC利用PagedList分页(一)
前几天看见博客园上有人写ASP.NET MVC的分页思想,这让我不禁想起了PagedList。PagedList是NuGet上提供的一个分页的类库,能对任何IEnumerable<T>进行分页,而且非常简单好用。从NuGet上,可以获取两个DLL:PagedList.dll和PagedList.Mvc.dll。PagedList.dll提供分页的核心操作,PagedList.Mvc.dll是一个辅助类库,在创建分页的UI时候提供简单、可扩展的创建方法。不过PagedList.dll可以用于MVC2及其以上,但是PagedList .Mvc.dll只能用于MVC3(及其以上)。
使用PagedList:
(一)、安装PagedList:引用-->Add Library Package Reference--->OnLine All--->搜索PagedList,点击Install安装。(如果没有安装Nuget,可以到下面地址下载:http://www.nuget.org/)
(二)、NuGet的好处就是我们不用再进行web.config等各种复杂的配置,所以下面直接编码:

using PagedList;
.....
//Controller:PersonController
public ViewResult Index(int? page)
{
int pageNumber = page ?? 1;
int pageSize = 2;
var persons = db.Persons.ToList();
return View(persons.ToPagedList(pageNumber, pageSize));
}
......
//View:Views/Person/Index
@model PagedList.PagedList<XXX.Person>
......
<div>
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber)
of @Model.PageCount @if (Model.HasPreviousPage)
{
@Html.ActionLink("<<", "Index", new { Page = 1 })
@Html.Raw(" ")
@Html.ActionLink("< Prve", "Index", new { Page = Model.PageNumber - 1 })
}
else
{
@:<<
@Html.Raw(" ")
@:< Prev
}
@Html.Raw(" ")
@if (Model.HasNextPage)
{
@Html.ActionLink("Next >", "Index", new { Page = Model.PageNumber + 1 })
@Html.Raw(" ")
@Html.ActionLink(">>", "Index", new { Page = Model.PageCount })
}
else
{
@:Next>
@Html.Raw(" ")
@:>>
}
</div>

是不是很简单一句简单的ToPageList就会返回一个强类型的PagedList.PagedList<T>对象,而且PagedList.PagedList<T>实现了IPagedList接口,通过对象浏览器我们可以看到IPagedList提供了很多方法和属性供我们在View绑定时候使用(例如HasPreviousPage、HasNextPage、PageCount、PageNumer等等),如下图:
不过还有两个问题:
第一、看了Controller中的代码,第一感觉是糟了。db.Persons.ToList() 太危险了,ToList时候数据已经执行,幻想一下,如果是百万甚至千万级的数据。。。所以这样不行。因为这里没有起到分页的效果。解决思路,赶紧组织其执行。
第二、View中绑定分页还有没有更好的方法,每次这样写是不是太费劲了呢?答案是肯定的,PagedList.Mvc.dll提供了分页导航功能。
利用PagedList优化分页:

//Controller: PersonController
public ViewResult Index(int? page)
{
int pageNumber = page ?? 1;
int pageSize = 2;
//Skip之前必须orderby
var persons = from p in db.Persons
orderby p.PersonID descending
select p;
return View(persons.ToPagedList(pageNumber, pageSize));
}

ok,这样就可以在分页前阻止查询的执行了。但是这里看到还是很虚的。PagedList为我们提供了StaticPagedList<T>类,而且我个人也比较推崇用它来进行分页查询:
public StaticPagedList(System.Collections.Generic.IEnumerable<T> subset, int pageNumber, int pageSize, int totalItemCount)
可以看到,StaticPagedList需要将:某一页的数据、页码、每页数据的容量、和数据总条目传入。也就是说这时候StaticPagedList不再像PagedList一样承担数据的划分工作,而仅仅承担数据的绑定操作。good。看个例子:

public ViewResult IndexTwo(int? page)
{
int pageIndex = page ?? 1;
int pageSize = 2;
int totalCount = 0;
var persons = GetPerson(pageIndex, pageSize, ref totalCount);
var personsAsIPagedList = new StaticPagedList<Person>(persons, pageIndex, pageSize, totalCount);
return View(personsAsIPagedList);
} public List<Person> GetPerson(int pageIndex, int pageSize, ref int totalCount)
{
var persons = (from p in db.Persons
orderby p.PersonID descending
select p).Skip((pageIndex - 1) * pageSize).Take(pageSize);
totalCount = db.Persons.Count();
return persons.ToList();
}

不过这里注意View中的@model PagedList.PagedList<XXX.Person>得换成@model PagedList.StaticPagedList<XXX.Person>额,因为返回的强类型对象不一样了。
PagedList.Mvc设置分页导航:
和上面一样安装Package.Mvc.dll,接下来看我们如何秒杀分页导航:

@model PagedList.StaticPagedList<XXX.Person>
@using PagedList
@using PagedList.Mvc ......
<link href="/Content/PagedList.css" rel="stylesheet" type="text/css" />
......
<div>
@Html.PagedListPager((IPagedList)Model, page => Url.Action("IndexPagedListMvc", new { page = page }))
</div>

将上面代码替换掉刚才View:Views/Person/Index中的代码,完了,你可以看到分页导航几乎和上面的差不多。PagedListed.MVC封装了分页导航的代码,如下图:
可以看到上面的HtmlHelper主要提供了两个扩展方法:PagedListPager和PagedListGoToPageForm。其中PagedListPager主要提供“上一页、下一页......”这类的导航方式(这里不知道怎么描述了),而PagedListGoToPageForm提供了input输入页面点击条状的导航方式,而PagedListRenderOptions和GoToFormRenderOptions分别问它们提供了配置选项。
PagedListPager配置选项
上面的例子使用了默认的配置选项,PagedListRenderOptions还提供了一下其他的配置选项,格式如下:
@Html.PagedListPager((IPagedList)Model, page => Url.Action("IndexPagedListMvc", new { page = page }),PagedListRenderOptions.XXX);
PagedListRenderOptions.XXX提供了更多配置属性,上面所说的配置选项也仅仅是这些配置属性的组合,我们还可以自己配置属性组合如下:
@Html.PagedListPager((IPagedList)Model, page => Url.Action("IndexPagedListMvc", new { page = page }),new PagedListRenderOptions{ LinkToPreviousPageFormat = "上一页", LinkToNextPageFormat = "下一页",MaximumPageNumbersToDisplay=5 });
越看越简单哇?哈哈哈除此之外,PagedList还为我们提供了分页导航的样式。上面的<link href="/Content/PagedList.css" rel="stylesheet" type="text/css" />就是引入分页导航的样式。你安装了PagedList.Mvc会自动的放在你的Content中,这既是NuGet的好处啊。。。。当然你也可以自定义Css和引用其他的Css,这里推荐一个最经一直比较火的Twiter BootStrap(官网地址为:http://twitter.github.com/bootstrap/,表示看不懂....什么12分格系统等看的我是一头雾水)的样式:
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css"> PagedListGoToPageFrom及其配置
@Html.PagedListGoToPageForm((IPagedList)Model, "IndexPagedListMvc");
@Html.PagedListGoToPageForm((IPagedList)Model, "IndexPagedListMvc",new GoToFormRenderOptions { XXX=xxx });
和PagedListRenderOptions不同,的GoToFromRenderOptions没有配置选项,其他的都差不多。
到目前为止,貌似两个问题都已经完全解决了,不过好的用户体验的分页肯定不希望点击下一页后有页面刷新的操作-------Ajax。由于涉及到jquery.templ.js,而我以前没有见过这个东东,所以先放下一下,后头再来说说PagedList+Ajax的分页和PagedList的实现原理。
ASP.NET MVC利用PagedList分页(一)的更多相关文章
- ASP.NET MVC利用PagedList分页(二)PagedList+Ajax+JsRender
(原文) 昨天在ASP.NET MVC利用PagedList分页(一)的 最后一节提到,一个好的用户体验绝对不可能是点击下一页后刷新页面,所以今天来说说利用Ajax+PagedList实现无刷新(个人 ...
- Asp.net Mvc使用PagedList分页
git:https://github.com/troygoode/PagedList 1. Nuget 安装package watermark/2/text/aHR0cDovL2Jsb2cuY3Nkb ...
- ASP.NET MVC之PagedList使用
ASP.NET MVC之PagedList使用 ---由于最近项目中用到了分页这里也来记录一下,一方面给自己一个记录,另一方面给后来者一些帮助! 一.首先大家先来看一下效果
- asp.net mvc easyui datagrid分页
提到 asp.net mvc 中的分页,很多是在用aspnetpager,和easyui datagrid结合的分页却不多,本文介绍的是利用easyui 中默认的分页控件,实现asp.net mvc分 ...
- [ASP.NET MVC] 利用动态注入HTML的方式来设计复杂页面
原文:[ASP.NET MVC] 利用动态注入HTML的方式来设计复杂页面 随着最终用户对用户体验需求的不断提高,实际上我们很多情况下已经在按照桌面应用的标准来设计Web应用,甚至很多Web页面本身就 ...
- 转:【译】Asp.net MVC 利用自定义RouteHandler来防止图片盗链
[译]Asp.net MVC 利用自定义RouteHandler来防止图片盗链 你曾经注意过在你服务器请求日志中多了很多对图片资源的请求吗?这可能是有人在他们的网站中盗链了你的图片所致,这会占用你 ...
- Asp.net MVC 使用PagedList(新的已更名 为X.PagedList.Mvc) 分页
在asp.net mvc 中,可以bootstrap来作为界面,自己来写分页程序.也可以使用PagedList(作者已更名为 X.PagedList.Mvc)来分页. 1.首先,在NuGet程序包管理 ...
- asp.net MVC 使用PagedList.MVC实现分页
在上一篇的EF之DB First中,存在以下的两个问题: 1. 添加/编辑页面显示的是属性名称,而非自定义的名称(如:姓名.专业...) 2. 添加/编辑时没有加入验证 另外数据展示使用分页 @Htm ...
- ASP.NET MVC 利用IRouteHandler, IHttpHandler实现图片防盗链
你曾经注意过在你服务器请求日志中多了很多对图片资源的请求吗?这可能是有人在他们的网站中盗链了你的图片所致,这会占用你的服务器带宽.下面这种方法可以告诉你如何在ASP.NET MVC中实现一个自定义Ro ...
随机推荐
- Chinese Mahjong UVA - 11210 (DFS)
先记录下每一种麻将出现的次数,然后枚举每一种可能得到的麻将,对于这个新的麻将牌,去判断可不可能胡,如果可以胡,就可以把这张牌输出出来. 因为eye只能有一张,所以这个是最好枚举的,就枚举每张牌成为ey ...
- 【洛谷P3901】数列找不同
题目大意:给定一个长度为 N 的序列,每个点被染了一个颜色.现有 M 个询问,每个询问查询区间 [l,r] 内的点是否颜色都是不同的. 题解:莫队裸题. 直接维护区间颜色数,用 cnt[] 记录下区间 ...
- 关于react-native项目在MacBookPro环境下打包成IPA
苹果开发者打包是需要接入公司的开发者账户里面的.看是企业账户还是什么,具体我不太清楚. 不过打包的方法倒是大同小异. 我们一起新建项目,先跑起来这个项目 npm install -g yarn rea ...
- MySQL 之 库操作,表操作
系统数据库 information_schema :虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数,如用户表信息.列信息.权限信息.字符信息等 mysql:核心数据库,里面包含用户.权限.关键 ...
- jmeter的介绍和使用一
一,jmeter介绍 1.官方网站下载jmeter,然后解压安装.我用的mac,用mac来讲解. 这是解压以后的包. 2.bin目录里面是一些可执行的文件 ,重点关注启动 如果是windows系统,直 ...
- Altium Designer 18 ------ 常用功能记录
PCB选中某条线路,按一下 Tab 键选中整条线路 PCB中,按 “N” 键选择隐藏或显示某个网络 配置Altium Designer 18 教程所需的捕捉网格的值: G显示Snap Grid菜单,您 ...
- consul介绍
consul 是一个支持多数据中心分布式高可用,用于服务发现和配置共享的工具. consul与其它工具的不同,官方介绍如下: https://www.consul.io/intro/vs/index. ...
- 运维监控-Open-Falcon安装Agent实战篇
运维监控-Open-Falcon安装Agent实战篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本文参考链接来自:http://book.open-falcon.org/zh/ ...
- Hadoop生态圈-Ranger数据安全管理框架
Hadoop生态圈-Ranger数据安全管理框架 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Ranger简介 Apache Ranger是一款被设计成全面掌握Hadoop生 ...
- script ajax / XHR / XMLHttpRequest
s 利用XHR 调试发送form data表单数据,F5键刷新form表单URL ,http请求地址,获取token,提交. 如:http://pcp.cns*****.com/spcp-web/vm ...