ASP.NET MVC 排序,筛选,分页(接上一篇适合新手练习的CRUD)
shangting 人气:3一、开始前准备
在上一篇 中我们使用 virtual studio制作了一个简单的小项目,下面的内容需要以此为基础,如果没有准备好的请看下面的链接。
ASP.NET MVC--适合新手练习的CRUD
请确保数据库可以正常使用。
二、排序
1.首先想要实现排序,我们需要在原来的基础上修改StudentController的Index方法,使其能够满足我们的需求。
这里我们添加了四种排序的方式:
- 按姓名升序(默认)
- 按姓名降序
- 按日期升序
- 按日期降序
此段代码将会接受一个sortOrder参数,首次请求的时候不会有查询字符串提交过来,学生将会按照默认的排序方式显示。
当点击排序链接后,查询字符串会提供一个sortOrder值。
三元语句。 第一个sortOrder
参数指定如果参数为 null 或为空, ViewBag.NameSortParm
则应将设置为 "name_desc"; 否则, 它应设置为空字符串。
ViewBag.NameSortParm = string.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
1 public ActionResult Index(string sortOrder) 2 { 3 ViewBag.NameSortParm = string.IsNullOrEmpty(sortOrder) ? "name_desc" : ""; 4 ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date"; 5 var students = from s in db.Students 6 select s; 7 switch (sortOrder) 8 { 9 case "name_desc": 10 students = students.OrderByDescending(s => s.Name); 11 break; 12 case "Date_desc": 13 students = students.OrderByDescending(s => s.EnrollmentDate); 14 break; 15 case "Date": 16 students = students.OrderBy(s => s.EnrollmentDate); 17 break; 18 default: 19 students = students.OrderBy(s => s.Name); 20 break; 21 } 22 return View(db.Students.ToList()); 23 }
2.添加视图中的链接
在Views/Student/Index.cshtml中,添加我们要点击的链接
1 @model IEnumerable<MyMvc.Models.Student> 2 3 @{ 4 ViewBag.Title = "Index"; 5 } 6 7 <h2>Index</h2> 8 9 <p> 10 @Html.ActionLink("Create New", "Create") 11 </p> 12 13 <table class="table"> 14 <tr> 15 <tr> 16 <th> 17 @Html.ActionLink("Name", "Index", new { sortOrder = ViewBag.NameSortParm}) 18 </th> 19 <th> 20 @Html.ActionLink("Gerder", "Index", new { sortOrder = ViewBag.GerSortParm }) 21 </th> 22 <th> 23 @Html.ActionLink("Enrollment Date","Index",new { sortOrder = ViewBag.DateSortParm}) 24 </th> 25 <th></th> 26 </tr> 27 <th> 28 @Html.DisplayNameFor(model=>model.Name) 29 </th> 30 <th> 31 @Html.DisplayNameFor(model=>model.Gerder) 32 </th> 33 <th> 34 @Html.DisplayNameFor(model=>model.EnrollmentDate) 35 </th> 36 37 <th></th> 38 </tr> 39 40 @foreach (var item in Model) 41 { 42 <tr> 43 <td> 44 @Html.DisplayFor(mt => item.Name) 45 </td> 46 <td> 47 @Html.DisplayFor(mt=>item.Gerder) 48 </td> 49 <td> 50 @Html.DisplayFor(mt=>item.EnrollmentDate) 51 </td> 52 <td> 53 @Html.ActionLink("Edit","Edit",new { id=item.Id}) 54 @Html.ActionLink("Details","Details",new { id=item.Id}) 55 @Html.ActionLink("Delete","Delete",new { id=item.Id}) 56 </td> 57 </tr> 58 } 59 </table>
我这里还加入了性别的排序,可以根据性别男女来排序。
ViewBag.GerSortParm = sortOrder == "Ger" ? "Ger_desc" : "Ger";
1 case "Ger": 2 students = students.OrderBy(s => s.Gerder); 3 break; 4 case "Ger_desc": 5 students = students.OrderByDescending(s => s.Gerder); 6 break;
大功告成!我们来运行测试一把。
点击蓝色的三个排序方法,皆可以实现我们想要的效果。
三、筛选(条件搜索)
1.继续修改StudentController的Index()方法,添加6-11行内容
仅当要搜索where的时候,才会执行where搜索子句。
1 ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : ""; 2 ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date"; 3 ViewBag.GerSortParm = sortOrder == "Ger" ? "Ger_desc" : "Ger"; 4 var students = from s in db.Students 5 select s; 6 if (!string.IsNullOrEmpty(searchString)) 7 { 8 students = students.Where(s => s.Name.Contains(searchString) 9 || s.Gerder.Contains(searchString) 10 ); 11 }
2.向视图中添加搜索框和按钮,7-13行
1 <h2>Index</h2> 2 3 <p> 4 @Html.ActionLink("Create New", "Create") 5 </p> 6 7 @using (Html.BeginForm()) 8 { 9 <p> 10 Find By Name/Gerder: @Html.TextBox("SearchString") 11 <input type="submit" value="Search" /> 12 </p> 13 }
3.话不多说,是骡子是马,拉出溜溜!运行~
搜索名字中含有a的学生,
仅展示男生的信息
四、分页
1.这里的分页我们使用PagedList来做,PagedList是一种良好的分页排序包,
首先安装PagedList NuGet包。在工具菜单中选择NuGet包管理器,选择程序包管理器控制台。
注意:一定要确认包源是NuGet.org,并且是在我们的工程项目之下。
2. 确认以上步骤后,输入一下命令
Install-Package PagedList.Mvc
稍等片刻,等待安装完成
3. OK!生成一下项目。ctrl+shift+B
4.向StudentController的Index添加分页方法,首先添加一句使用命名空间的语句。
using PagedList;
1 public ActionResult Index(string sortOrder, string searchString,string currentFilter, int? page) 2 { 3 ViewBag.currentFilter = sortOrder; 4 ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : ""; 5 ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date"; 6 ViewBag.GerSortParm = sortOrder == "Ger" ? "Ger_desc" : "Ger"; 7 8 if (searchString != null) 9 { 10 page = 1; 11 } 12 else { 13 searchString = currentFilter; 14 } 15 16 ViewBag.CurrentFilter = searchString; 17 var students = from s in db.Students 18 select s; 19 if (!string.IsNullOrEmpty(searchString)) 20 { 21 students = students.Where(s => s.Name.Contains(searchString) 22 || s.Gerder.Contains(searchString) 23 ); 24 } 25 switch (sortOrder) 26 { 27 case "name_desc": 28 students = students.OrderByDescending(s => s.Name); 29 break; 30 case "Date": 31 students = students.OrderBy(s => s.EnrollmentDate); 32 break; 33 case "date_desc": 34 students = students.OrderByDescending(s => s.EnrollmentDate); 35 break; 36 case "Ger": 37 students = students.OrderBy(s => s.Gerder); 38 break; 39 case "Ger_desc": 40 students = students.OrderByDescending(s => s.Gerder); 41 break; 42 default: 43 students = students.OrderBy(s => s.Name); 44 break; 45 } 46 int pageSize = 3; 47 int pageNumber = (page ?? 1); 48 return View(students.ToPagedList(pageNumber,pageSize)); 49 }
第一次显示页面时, 或如果用户未单击分页或排序链接, 则所有参数都为 null。 如果单击了某个页面链接, 则page
该变量将包含要显示的页码。
ViewBag
属性提供当前排序顺序的视图, 因为它必须包含在分页链接中, 以便在分页时保持排序顺序相同:
ViewBag.CurrentSort = sortOrder;
ViewBag.CurrentFilter
提供当前筛选器字符串的视图。
如果在分页过程中搜索字符串发生变化,页面必须重置为 1,因为新的筛选器会导致显示不同的数据。 在文本框中输入值并按 "提交" 按钮时, 将更改搜索字符串。
在这种情况下searchString
, 参数不为 null。
1 if (searchString != null) 2 { 3 page = 1; 4 } 5 else 6 { 7 searchString = currentFilter; 8 }
两个问号表示null合并运算符。 NULL 合并运算符为可为 NULL 的类型定义默认值;表达式 (page ?? 1)
表示如果 page
有值,则返回该值,如果 page
为 NULL,则返回 1。
int pageSize = 3; int pageNumber = (page ?? 1); return View(students.ToPagedList(pageNumber, pageSize));
5.向Index.cshtml视图添加链接
添加的过程中,要注意修改38-49行,当Model变为PagedList<Model>之后,DisPlayNameFor将无法找到对应的类型,会报错,这时可以将DisPlayNameFor更改为DisPlayName(弱类型)。
1 @model PagedList.IPagedList<MyMvc.Models.Student> 2 @using PagedList.Mvc 3 @using MyMvc.Models; 4 <link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" /> 5 6 @{ 7 ViewBag.Title = "Students"; 8 } 9 10 <h2>Students</h2> 11 12 <p> 13 @Html.ActionLink("Create New", "Create") 14 </p> 15 16 @using (Html.BeginForm("Index", "Student", FormMethod.Get)) 17 { 18 <p> 19 Find By Name/Gender: @Html.TextBox("SearchString", ViewBag.CurrentFilter as string) 20 <input type="submit" value="Search" /> 21 </p> 22 } 23 <table class="table"> 24 25 <tr> 26 <th> 27 @Html.ActionLink("Sort By Name", "Index", new { sortOrder = ViewBag.NameSortParm, currentFilter = ViewBag.CurrentFilter }) 28 </th> 29 <th> 30 @Html.ActionLink("Sort By Gerder", "Index", new { sortOrder = ViewBag.GerSortParm, currentFilter = ViewBag.CurrentFilter }) 31 </th> 32 <th> 33 @Html.ActionLink("Sort By Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm, currentFilter = ViewBag.CurrentFilter }) 34 </th> 35 <th></th> 36 </tr> 37 <tr> 38 <th> 39 @Html.DisplayName("Name") 40 </th> 41 <th> 42 @Html.DisplayName("Gerder") 43 </th> 44 <th> 45 @Html.DisplayName("EnrollmentDate") 46 </th> 47 <th> 48 @Html.DisplayName("Options") 49 </th> 50 </tr> 51 52 @foreach (var item in Model) 53 { 54 <tr> 55 <td> 56 @Html.DisplayFor(mt => item.Name) 57 </td> 58 <td> 59 @Html.DisplayFor(mt => item.Gerder) 60 </td> 61 <td> 62 @Html.DisplayFor(mt => item.EnrollmentDate) 63 </td> 64 <td> 65 @Html.ActionLink("Edit", "Edit", new { id = item.Id }) 66 @Html.ActionLink("Details", "Details", new { id = item.Id }) 67 @Html.ActionLink("Delete", "Delete", new { id = item.Id }) 68 </td> 69 </tr> 70 } 71 </table> 72 <br /> 73 Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount 74 75 @Html.PagedListPager(Model, page => Url.Action("Index", 76 new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
默认html.beginform使用 POST 提交窗体数据, 这意味着参数将在 HTTP 消息正文中传递, 而不是作为查询字符串在 URL 中传递。
当指定 HTTP GET 时,表单数据作为查询字符串在 URL 中传递.
6.最后一步,跑起来!
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
到这里,我们这篇文章的主要三大功能就完成了。我们接着来做一个“关于”的页面
五、创建一个“About”页面
1.创建视图模型
在项目下新建一个文件夹,命名viewmodel,然后添加一个实体类
EnrollmentDateGroup.cs
1 public class EnrollmentDateGroup 2 { 3 [DataType(DataType.Date)] 4 public DateTime? EnrollmentDate { get; set; } 5 6 public int StudentCount { get; set; } 7 }
2.修改主控制器
在HomeController引入DAL,viewmodel
为数据库上下文添加类变量
public class HomeController : Controller { private SchoolContext db = new SchoolContext();
然后添加About方法
LINQ 语句按注册日期对学生实体进行分组,计算每组中实体的数量,并将结果存储在 EnrollmentDateGroup
视图模型对象的集合中。
public ActionResult About() { IQueryable<EnrollmentDateGroup> data = from student in db.Students group student by student.EnrollmentDate into dateGroup select new EnrollmentDateGroup() { EnrollmentDate = dateGroup.Key, StudentCount = dateGroup.Count() }; return View(data.ToList()); }
添加dispose方法
protected override void Dispose(bool disposing) { db.Dispose(); base.Dispose(disposing); }
3.添加About.cshtml
在About右键选择添加视图,然后修改About.cshtml
1 @model IEnumerable<MyMvc.viewmodel.EnrollmentDateGroup> 2 3 @{ 4 ViewBag.Title = "Student Body Statistics"; 5 } 6 7 <h2>Student Body Statistics</h2> 8 9 <table> 10 <tr> 11 <th> 12 Enrollment Date 13 </th> 14 <th> 15 Students 16 </th> 17 </tr> 18 19 @foreach (var item in Model) 20 { 21 <tr> 22 <td> 23 @Html.DisplayFor(modelItem => item.EnrollmentDate) 24 </td> 25 <td> 26 @item.StudentCount 27 </td> 28 </tr> 29 } 30 </table>
4.运行
点击About链接
结束。
加载全部内容