前言

上一节我们做到了如下的一个基础查询页面。本节我们向这个页面中加入排序、搜索和分页功能。

排序

从上图中的地址栏中可以看到这个页面调用的是Company Controller下的Index Action.因此我们就先打开Controllers文件夹下的CompanyController.cs文件,写入如下代码:

 1 using System.Linq;
2 using System.Web.Mvc;
3 using SlarkInc.DAL;
4 using System;
5 6 namespace SlarkInc.Controllers
7 {
8 public class CompanyController : Controller
9 {
10 private CompanyContext db = new CompanyContext();
11 public ViewResult Index(string sortOrder)
12 {
13 ViewBag.FirstNameSortParm = String.IsNullOrEmpty(sortOrder) ? "first_desc" : "";
14 ViewBag.LastNameSortParm = sortOrder == "last" ? "last_desc" : "last";
15 var workers = from w in db.Workers
16 select w;
17 switch (sortOrder)
18 {
19 case "first_desc":
20 workers = workers.OrderByDescending(w => w.FirstName);
21 break;
22 case "last_desc":
23 workers = workers.OrderByDescending(w => w.LastName);
24 break;
25 case "last":
26 workers = workers.OrderBy(w => w.LastName);
27 break;
28 default:
29 workers = workers.OrderBy(w => w.FirstName);
30 break;
31 }
32 return View(workers.ToList());
33 }
34 }
35 }

第11行,Index Action 的参数sortOrder用来传递给Controller排序的信息。sortOrder有4个可能值。这4个值体现在17到31行的switch..case语句中。如果是first_desc则对FirstName用OrderByDescending倒序排列。如果是last_desc则对LastName倒序排列。如果是last则对LastName用OrderBy函数顺序排列。如果是空则对FirstName顺序排列。第13-14行用Viewbag存储当前排列的相反排列字符串,用于在View中生成链接。第15-16行,用Linq to Entity 从数据库中选取要排序的数据。第32行将排序好的数据以List的形式传递给View。

在对应的View文件~\Views\Company\Index.cshtml中,修改其表头部分,代码如下。

<tr><th>
@Html.ActionLink("First Name", "Index", new { sortOrder = ViewBag.FirstNameSortParm })
</th><th>
@Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.LastNameSortParm })
</th><th>@Html.DisplayNameFor(model => model.Sex)</th><th>@Html.DisplayNameFor(model => model.Rating)</th></tr>

黄色的部分为修改后的代码。我们把以前纯文本的表头改成一个超链接,链接的参数从ViewBag中获得。点击链接可以获得与当前排序相反的排序效果。

通过浏览器查看此页面。之后点击LastName链接,则按照上面代码会生成如下页面:

参数sortOrder为last则这个表按lastName顺序排列。

搜索

一般查询页面都会有搜索功能帮助我们查看自己想要的页面。下面我们就来实现这个功能。

还是从Controller开始,Index Action的代码写成如下形式:

 1 public ViewResult Index(string sortOrder, string searchString)
2 {
3 ViewBag.FirstNameSortParm = String.IsNullOrEmpty(sortOrder) ? "first_desc" : "";
4 ViewBag.LastNameSortParm = sortOrder == "last" ? "last_desc" : "last";
5 var workers = from w in db.Workers
6 select w;
7 if (!string.IsNullOrEmpty(searchString))
8 {
9 workers = workers.Where(w => w.FirstName.Contains(searchString)
10 || w.LastName.Contains(searchString));
11 }
12 switch (sortOrder)
13 {
14 case "first_desc":
15 workers = workers.OrderByDescending(w => w.FirstName);
16 break;
17 case "last_desc":
18 workers = workers.OrderByDescending(w => w.LastName);
19 break;
20 case "last":
21 workers = workers.OrderBy(w => w.LastName);
22 break;
23 default:
24 workers = workers.OrderBy(w => w.FirstName);
25 break;
26 }
27 return View(workers.ToList());
28 }

上面代码中黄色的部分就是我们所添加的。第1行,searchString向Controller传递用来搜索的字符串。第7行,字符串不为空时执行搜索。这里的搜索用到了Linq里的Where函数,它通过一个Lambda表达式来筛选出符合条件的数据。这个条件就是9-10行的"或"连接的两个Contains函数。Contains函数表示其所属字符串是否包含其参数字符串。整个筛选条件表示返回所有FisrtName或LastName包含筛选字符串的记录。

下面看~\Views\Company\Index.cshtml的改动:

@using(Html.BeginForm())
{
<p>
Find by name: @Html.TextBox("SearchString","", new { @class = "form-control", @Style = "display:inline" })
@Html.Submit("Submit")
</p>
}

在table的上面加入这些代码,它是一个Form,包含一个输入框和提交按钮,这个Form会把输入框中的搜索字符串提交给当前Controller完成搜索操作。其中的输入框,加入了class和style对其进行了Bootstrap美化。

通过浏览器查看这个页面,在搜索框中输入b并且提交,之后会出现如下页面:

可以看到搜索结果是FirstName或LastName包含b(不分大小写),的所有记录。

分页

数据查询免不了要分页。这里我们用一个名为PagedList的插件来实现这个功能。

如下所示,在菜单栏里选择工具->库程序包管理->程序包管理控制台。

之后会在Visual Studio窗口的下面看到一个程序包管理控制台窗口。在其中输入Install-Package PagedList.Mvc。PagedList就会自动安装到项目中。窗口如下所示。

Paged List 安装好后,我们就开始修改代码,从Controller开始:

 1 using System.Linq;
2 using System.Web.Mvc;
3 using SlarkInc.DAL;
4 using System;
5 using PagedList;
6 7 namespace SlarkInc.Controllers
8 {
9 public class CompanyController : Controller
10 {
11 private CompanyContext db = new CompanyContext();
12 public ViewResult Index(string sortOrder, string searchString, string currentFilter, int? page)
13 {
14 ViewBag.CurrentSort = sortOrder;
15 ViewBag.FirstNameSortParm = String.IsNullOrEmpty(sortOrder) ? "first_desc" : "";
16 ViewBag.LastNameSortParm = sortOrder == "last" ? "last_desc" : "last";
17 if(searchString != null)
18 {
19 page = 1;
20 }
21 else {
23 searchString = currentFilter;
24 }
25 ViewBag.CurrentFilter = searchString;
2627 var workers = from w in db.Workers
28 select w;
29 if (!string.IsNullOrEmpty(searchString))
30 {
31 workers = workers.Where(w => w.FirstName.Contains(searchString)
32 || w.LastName.Contains(searchString));
33 }
34 switch (sortOrder)
35 {
36 case "first_desc":
37 workers = workers.OrderByDescending(w => w.FirstName);
38 break;
39 case "last_desc":
40 workers = workers.OrderByDescending(w => w.LastName);
41 break;
42 case "last":
43 workers = workers.OrderBy(w => w.LastName);
44 break;
45 default:
46 workers = workers.OrderBy(w => w.FirstName);
47 break;
48 }
49 int pageSize = 3;
50 int pageNumber = (page ?? 1);
51 return View(workers.ToPagedList(pageNumber,pageSize));
52 }
53 }
54 }

黄色标记的为需要改动的部分。第5行,需要引用PagedList。第12行currentFilter参数用来在翻页时保持搜索字符串不丢失。第17到25行的作用是,当有一个新的字符串要搜索,那么翻当前页就自动变成第一页,否则,当前页不变。第49-51行设置每页3条数据,设置页数,并将数据以List的形式发送个View。其中(page ?? 1)的意思是如果page为null则给page赋值为1否则,page不为null那么该是多少就是多少。所以能让默认页为1.

 1 @model PagedList.IPagedList<SlarkInc.Models.Worker> 
2 @using PagedList.Mvc;
3 <link href="~/Content/PagedList.css" rel="stylesheet" />
4 <br />
5 @using(Html.BeginForm("Index","Company",FormMethod.Get))
6 {
7 <p> 8 Find by name: @Html.TextBox("SearchString",ViewBag.CurrentFilter as string, new { @class = "form-control", @Style = "display:inline" })
9 @Html.Submit("Submit")
10 </p>11 }
12 <table class="table">13 <tr>14 <th>15 @Html.ActionLink("First Name", "Index", new { sortOrder = ViewBag.FirstNameSortParm })
16 </th>17 <th>18 @Html.ActionLink("Last Name", "Index", new { sortOrder = ViewBag.LastNameSortParm })
19 </th>20 <th>Sex</th>21 <th>Rating</th>22 </tr>23 @foreach (var item in Model)
24 {
25 <tr>26 <td>27 @Html.DisplayFor(modelItem => item.FirstName)
28 </td>29 <td>30 @Html.DisplayFor(modelItem => item.LastName)
31 </td>32 <td>33 @Html.DisplayFor(modelItem => item.Sex)
34 </td>35 <td>36 @Html.DisplayFor(modelItem => item.Rating)
37 </td>38 </tr>39 }
40 </table>41 <br/>42 Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
43 @Html.PagedListPager(Model, page => Url.Action("Index",
44 new {page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter}))

第1行定义了PagedList 类型的model。第2行引用PagedList。第3行,引入,PagedList相关的css文件,这个文件在安装插件的时候会自动保存到项目里。第5行BeginForm函数的参数有变化,其生成的Form会使用Get方法。Get方法会在url里显示提交的参数,这样可以通过url来记录查询参数,方便通过复制url给他人来展现自己的查询结果。第42行用于显示第几页,共几页。第43-44行,用于生成每一页的按钮。

运行此页面,当页面出来时点击页面下方的"2"按钮转到第2页。生成的页面如下所示:

可以看到页面下方的分页按钮和页数统计,美观大方。

ASP.Net MVC4排序检索分页的实现的更多相关文章

  1. asp.net core 排序过滤分页组件:sieve(1)

    使用asp.net core开发时避免不了要用一个合适的分页组件来让前端获取分页数据.github上面有一个开源的分页组件在这方面很适合我的使用,于是我把他的文档翻译一下,随后会分析它里面的源码.这是 ...

  2. asp.net core 排序过滤分页组件:sieve(2)表达式树的复习

    在Sieve组件中使用了很多关于表达式树的知识,但在我们日常的工作中写表达式树的机会是非常少的,至少在我的编程生涯中没怎么写过表达式树(可能也就是3,4次).所以,为了能够看懂Sieve里面的源代码, ...

  3. 在ASP.NET MVC5中实现具有服务器端过滤、排序和分页的GridView

    背景 在前一篇文章<[初学者指南]在ASP.NET MVC 5中创建GridView>中,我们学习了如何在 ASP.NET MVC 中实现 GridView,类似于 ASP.NET web ...

  4. [转]在ASP.NET MVC5中实现具有服务器端过滤、排序和分页的GridView

    本文转自:http://www.cnblogs.com/powertoolsteam/p/MVC5_GridView_2.html 背景 在前一篇文章<[初学者指南]在ASP.NET MVC 5 ...

  5. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(17)-LinQ动态排序

    原文:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(17)-LinQ动态排序 首先修复程序中的一个BUG这个BUG在GridPager类中,把sord修改为s ...

  6. [原创]java WEB学习笔记92:Hibernate学习之路-- -QBC 检索和本地 SQL 检索:基本的QBC 查询,带 AND 和 OR 的QBC,统计查询,排序,分页

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  7. ASP.NET MVC with Entity Framework and CSS一书翻译系列文章之第五章:排序、分页和路由

    本章的重点是对产品信息增加排序和分页的功能,以及使用ASP.NET Routing特性添加更加友好的URL支持. 注意:如果你想按照本章的代码编写示例,你必须完成第四章或者直接从www.apress. ...

  8. 在ASP.NET MVC中使用Boostrap实现产品的展示、查询、排序、分页

    在产品展示中,通常涉及产品的展示方式.查询.排序.分页,本篇就在ASP.NET MVC下,使用Boostrap来实现. 源码放在了GitHub: https://github.com/darrenji ...

  9. ASP.NET MVC4入门到精通系列目录汇总

    序言 最近公司在招.NET程序员,我发现好多来公司面试的.NET程序员居然都没有 ASP.NET MVC项目经验,其中包括一些工作4.5年了,甚至8年10年的,许多人给我的感觉是:工作了4.5年,We ...

随机推荐

  1. 字符串(后缀自动机):USACO Dec10 恐吓信

    [题目描述] FJ刚刚和邻居发生了一场可怕的争吵,他咽不下这口气,决定佚名发给他的邻居一封脏话连篇的信.他有无限张完全相同的已经打印好的信件,都包含 N个字母(1<=N<=50,000). ...

  2. SQL中的NULL值

    除is [not] null之外,空值不满足任何查找条件.–如果null参与算术运算,则该算术表达式的值为null.–如果null参与比较运算,则结果可视为false.在SQL-92中可看成unkno ...

  3. <离散数学>学习笔记1--逻辑和证明

    今天开始离散数学的自学旅程. 主题:逻辑和证明 逻辑规则给出数学语句的准确含义.逻辑对计算机科学有着重要作用.为了理解数学,我么必须理解正确的数学论证是由什么组成的.只要证明一个数学语句是真的,我们就 ...

  4. JavaScript使用需要注意的细节

    1.JavaScript区分大小写 在JavaScript中对象,变量.函数都是区分大小写的,例如: Object表示对象,Arrary表示数组,而写成object,arrary的时候JavaScri ...

  5. [Javascript] String method: endsWith() && startsWith()

    With endsWith && startsWith, you can easily find out whether the string ends or starts with ...

  6. [Angular 2] @ngrx/devtools demo

    Check the Github: https://github.com/ngrx/devtools Example:

  7. [CSS3] Text ellipsis

    Link: http://www.w3schools.com/cssref/tryit.asp?filename=trycss3_text-overflow div{ white-space: now ...

  8. [yueqian_scut]蓝牙防丢器原理、实现与Android BLE接口编程

    本文是对已实现的蓝牙防丢器项目的总结,阐述蓝牙防丢器的原理.实现与Android客户端的蓝牙BLE接口编程.在这里重点关注如何利用BLE接口来进行工程实现,对于BLE的协议.涉及到JNI的BLE接口内 ...

  9. 浅析mysql 共享表空间与独享表空间以及他们之间的转化

        innodb这种引擎,与MYISAM引擎的区别很大.特别是它的数据存储格式等.对于innodb的数据结构,首先要解决两个概念性的问题: 共享表空间以及独占表空间.什么是共享表空间和独占表空间共 ...

  10. [转] Javascript中数组与字典(即object)的使用

    简述: 简单记录一下数据结构字典和数组, 其实在Javascript这种弱类型的脚本语言中,数组同时也就是字典,下面主要就是字典数组的简易使用 代码: 1. 数组中添加map <!DOCTYPE ...