一, 开始前准备
在上一篇 中我们使用 virtual studio 制作了一个简单的小项目, 下面的内容需要以此为基础, 如果没有准备好的请看下面的链接.
ASP.NET MVC-- 适合新手练习的 CRUD
请确保数据库可以正常使用.
二, 排序
1. 首先想要实现排序, 我们需要在原来的基础上修改 StudentController 的 Index 方法, 使其能够满足我们的需求.
这里我们添加了四种排序的方式:
按姓名升序 (默认)
按姓名降序
按日期升序
按日期降序
此段代码将会接受一个 sortOrder 参数, 首次请求的时候不会有查询字符串提交过来, 学生将会按照默认的排序方式显示.
当点击排序链接后, 查询字符串会提供一个 sortOrder 值.
三元语句. 第一个 sortOrder 参数指定如果参数为 null 或为空, ViewBag.NameSortParm 则应将设置为 "name_desc"; 否则, 它应设置为空字符串.
- ViewBag.NameSortParm = string.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
- public ActionResult Index(string sortOrder)
- {
- ViewBag.NameSortParm = string.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
- ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date";
- var students = from s in db.Students
- select s;
- switch (sortOrder)
- {
- case "name_desc":
- students = students.OrderByDescending(s => s.Name);
- break;
- case "Date_desc":
- students = students.OrderByDescending(s => s.EnrollmentDate);
- break;
- case "Date":
- students = students.OrderBy(s => s.EnrollmentDate);
- break;
- default:
- students = students.OrderBy(s => s.Name);
- break;
- }
- return View(db.Students.ToList());
- }
2. 添加视图中的链接
在 Views/Student/Index.cshtml 中, 添加我们要点击的链接
@model IEnumerable<MyMvc.Models.Student> @{ ViewBag.Title = "Index"; } <h2>Index</h2> <p> @HTML.ActionLink("Create New", "Create") </p> <table class="table"> <tr> <tr> <th> @HTML.ActionLink("Name", "Index", new { sortOrder = ViewBag.NameSortParm}) </th> <th> @HTML.ActionLink("Gerder", "Index", new { sortOrder = ViewBag.GerSortParm }) </th> <th> @HTML.ActionLink("Enrollment Date","Index",new { sortOrder = ViewBag.DateSortParm}) </th> <th></th> </tr> <th> @HTML.DisplayNameFor(model=>model.Name) </th> <th> @HTML.DisplayNameFor(model=>model.Gerder) </th> <th> @HTML.DisplayNameFor(model=>model.EnrollmentDate) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @HTML.DisplayFor(mt => item.Name) </td> <td> @HTML.DisplayFor(mt=>item.Gerder) </td> <td> @HTML.DisplayFor(mt=>item.EnrollmentDate) </td> <td> @HTML.ActionLink("Edit","Edit",new { id=item.Id}) @HTML.ActionLink("Details","Details",new { id=item.Id}) @HTML.ActionLink("Delete","Delete",new { id=item.Id}) </td> </tr> } </table>
我这里还加入了性别的排序, 可以根据性别男女来排序.
ViewBag.GerSortParm = sortOrder == "Ger" ? "Ger_desc" : "Ger"; case "Ger": students = students.OrderBy(s => s.Gerder); break; case "Ger_desc": students = students.OrderByDescending(s => s.Gerder); break;
大功告成! 我们来运行测试一把.
点击蓝色的三个排序方法, 皆可以实现我们想要的效果.
三, 筛选 (条件搜索)
1. 继续修改 StudentController 的 Index() 方法, 添加 6-11 行内容
仅当要搜索 where 的时候, 才会执行 where 搜索子句.
ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : ""; ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date"; ViewBag.GerSortParm = sortOrder == "Ger" ? "Ger_desc" : "Ger"; var students = from s in db.Students select s; if (!string.IsNullOrEmpty(searchString)) { students = students.Where(s => s.Name.Contains(searchString) || s.Gerder.Contains(searchString) ); }
2. 向视图中添加搜索框和按钮, 7-13 行
<h2>Index</h2> <p> @HTML.ActionLink("Create New", "Create") </p> @using (HTML.BeginForm()) { <p> Find By Name/Gerder: @HTML.TextBox("SearchString") <input type="submit" value="Search" /> </p> }
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; public ActionResult Index(string sortOrder, string searchString,string currentFilter, int? page) { ViewBag.currentFilter = sortOrder; ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : ""; ViewBag.DateSortParm = sortOrder == "Date" ? "date_desc" : "Date"; ViewBag.GerSortParm = sortOrder == "Ger" ? "Ger_desc" : "Ger"; if (searchString != null) { page = 1; } else { searchString = currentFilter; } ViewBag.CurrentFilter = searchString; var students = from s in db.Students select s; if (!string.IsNullOrEmpty(searchString)) { students = students.Where(s => s.Name.Contains(searchString) || s.Gerder.Contains(searchString) ); } switch (sortOrder) { case "name_desc": students = students.OrderByDescending(s => s.Name); break; case "Date": students = students.OrderBy(s => s.EnrollmentDate); break; case "date_desc": students = students.OrderByDescending(s => s.EnrollmentDate); break; case "Ger": students = students.OrderBy(s => s.Gerder); break; case "Ger_desc": students = students.OrderByDescending(s => s.Gerder); break; default: students = students.OrderBy(s => s.Name); break; } int pageSize = 3; int pageNumber = (page ?? 1); return View(students.ToPagedList(pageNumber,pageSize)); }
第一次显示页面时, 或如果用户未单击分页或排序链接, 则所有参数都为 null. 如果单击了某个页面链接, 则 page 该变量将包含要显示的页码.
ViewBag 属性提供当前排序顺序的视图, 因为它必须包含在分页链接中, 以便在分页时保持排序顺序相同:
ViewBag.CurrentSort = sortOrder;
ViewBag.CurrentFilter 提供当前筛选器字符串的视图.
如果在分页过程中搜索字符串发生变化, 页面必须重置为 1, 因为新的筛选器会导致显示不同的数据. 在文本框中输入值并按 "提交" 按钮时, 将更改搜索字符串.
在这种情况下 searchString , 参数不为 null.
if (searchString != null) { page = 1; } else { searchString = currentFilter; }
两个问号表示 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(弱类型).
@model PagedList.IPagedList<MyMvc.Models.Student> @using PagedList.Mvc @using MyMvc.Models; <link href="~/Content/PagedList.CSS" rel="stylesheet" type="text/css" /> @{ ViewBag.Title = "Students"; } <h2>Students</h2> <p> @HTML.ActionLink("Create New", "Create") </p> @using (HTML.BeginForm("Index", "Student", FormMethod.Get)) { <p> Find By Name/Gender: @HTML.TextBox("SearchString", ViewBag.CurrentFilter as string) <input type="submit" value="Search" /> </p> } <table class="table"> <tr> <th> @HTML.ActionLink("Sort By Name", "Index", new { sortOrder = ViewBag.NameSortParm, currentFilter = ViewBag.CurrentFilter }) </th> <th> @HTML.ActionLink("Sort By Gerder", "Index", new { sortOrder = ViewBag.GerSortParm, currentFilter = ViewBag.CurrentFilter }) </th> <th> @HTML.ActionLink("Sort By Enrollment Date", "Index", new { sortOrder = ViewBag.DateSortParm, currentFilter = ViewBag.CurrentFilter }) </th> <th></th> </tr> <tr> <th> @HTML.DisplayName("Name") </th> <th> @HTML.DisplayName("Gerder") </th> <th> @HTML.DisplayName("EnrollmentDate") </th> <th> @HTML.DisplayName("Options") </th> </tr> @foreach (var item in Model) { <tr> <td> @HTML.DisplayFor(mt => item.Name) </td> <td> @HTML.DisplayFor(mt => item.Gerder) </td> <td> @HTML.DisplayFor(mt => item.EnrollmentDate) </td> <td> @HTML.ActionLink("Edit", "Edit", new { id = item.Id }) @HTML.ActionLink("Details", "Details", new { id = item.Id }) @HTML.ActionLink("Delete", "Delete", new { id = item.Id }) </td> </tr> } </table> <br /> Page @(Model.PageCount <Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount @HTML.PagedListPager(Model, page => Url.Action("Index", new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
默认 HTML.beginform 使用 POST 提交窗体数据, 这意味着参数将在 HTTP 消息正文中传递, 而不是作为查询字符串在 URL 中传递.
当指定 HTTP GET 时, 表单数据作为查询字符串在 URL 中传递.
6. 最后一步, 跑起来!
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
到这里, 我们这篇文章的主要三大功能就完成了. 我们接着来做一个 "关于" 的页面
五, 创建一个 "About" 页面
1. 创建视图模型
在项目下新建一个文件夹, 命名 viewmodel, 然后添加一个实体类
EnrollmentDateGroup.cs
public class EnrollmentDateGroup { [DataType(DataType.Date)] public DateTime? EnrollmentDate { get; set; } public int StudentCount { get; set; } }
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
@model IEnumerable<MyMvc.viewmodel.EnrollmentDateGroup> @{ ViewBag.Title = "Student Body Statistics"; } <h2>Student Body Statistics</h2> <table> <tr> <th> Enrollment Date </th> <th> Students </th> </tr> @foreach (var item in Model) { <tr> <td> @HTML.DisplayFor(modelItem => item.EnrollmentDate) </td> <td> @item.StudentCount </td> </tr> } </table>
4. 运行
点击 About 链接
结束.
来源: https://www.cnblogs.com/shangting/p/12102494.html