[翻译]ASP.NET MVC 3 开发的20个秘诀(九)[20 Recipes for Programming MVC 3]:对列表进行筛选
2011-12-14 12:33
686 查看
[b]议题[/b]
当排序和分页不能帮助用户找到他们需要的结果,那就根据条件筛选内容的方式来帮助他们寻找。
[b]解决方案[/b]
添加一个新的链接可以让用户选择预制的标准内容通过Linq Library对列表内容进行数据筛选。
[b]讨论[/b]
添加筛选链接,需要修改Books视图、Index视图和BookController控制器。修改与前两个秘诀类似,添加HTML链接,内容必须是允许用户选择的内容。添加三个新链接:全部、新发布和即将发布。新发布的内容是最近两周发布的内容。即将发布的内容是预告未来发布的内容。
下面是新的Books和Index视图。三个链接中都会包含排序规则的参数(以便保持当前用户的排序选项),后两个链接会包含一个名为“filter”的新的变量参数。与分页链接类似,激活的筛选器只显示链接,未激活的显示文字链接,以标识用户当前选定的筛选器选项。为了在用户更改排序选项时也能保持当前筛选器的选项,也需要按照当前筛选器更新:
在之前我们创建的分页链接的分部视图中,也需要做这样的修改。在下面的代码中,四个分页链接中也需要传送当前页码、排序规则和筛选器选项:
接下来,再对BooksController中的Index()方法进行修改。接受一个新的筛选器变量,根据用户选择的筛选器,将会减少书籍列表的数量。有以下两种实现方式:
为Linq添加Where的字符串选择条件;
使用标准Linq的强类型选择条件。
由于通常筛选器通常不会包含太多条目,所以在这个秘诀中我们将使用第二种方法。使用第二种方法的时候,因为条目是预制的且是强类型的并不是动态的,所以不需要额外的输入检查或SQL注入防治。
在上面的例子中,用户可以筛选最新的内容并搜索返回今天或过去14天发布的书籍,又或者用户也可以选择即将发布并搜索返回任何今天出版的书籍。否则,没有选择任何筛选器就会返回所有书籍。
[b]参考[/b]
原书地址 书籍源代码
当排序和分页不能帮助用户找到他们需要的结果,那就根据条件筛选内容的方式来帮助他们寻找。
[b]解决方案[/b]
添加一个新的链接可以让用户选择预制的标准内容通过Linq Library对列表内容进行数据筛选。
[b]讨论[/b]
添加筛选链接,需要修改Books视图、Index视图和BookController控制器。修改与前两个秘诀类似,添加HTML链接,内容必须是允许用户选择的内容。添加三个新链接:全部、新发布和即将发布。新发布的内容是最近两周发布的内容。即将发布的内容是预告未来发布的内容。
下面是新的Books和Index视图。三个链接中都会包含排序规则的参数(以便保持当前用户的排序选项),后两个链接会包含一个名为“filter”的新的变量参数。与分页链接类似,激活的筛选器只显示链接,未激活的显示文字链接,以标识用户当前选定的筛选器选项。为了在用户更改排序选项时也能保持当前筛选器的选项,也需要按照当前筛选器更新:
@model PagedList.IPagedList<MvcApplication4.Models.Book> <h2>@MvcApplication4.Resources.Resource1.BookIndexTitle</h2> <p> @Html.ActionLink("Create New", "Create") </p> <p> Show: @if (ViewBag.CurrentFilter != "") { @Html.ActionLink("All", "Index", new { sortOrder = ViewBag.CurrentSortOrder }) } else { @:All } | @if (ViewBag.CurrentFilter != "NewReleases") { @Html.ActionLink("New Releases", "Index", new { filter = "NewReleases", sortOrder = ViewBag.CurrentSortOrder }) } else { @:New Releases } | @if (ViewBag.CurrentFilter != "ComingSoon") { @Html.ActionLink("Coming Soon", "Index", new { filter = "ComingSoon", sortOrder = ViewBag.CurrentSortOrder }) } else { @:Coming Soon } </p> @Html.Partial("_Paging") <table> <tr> <th> @Html.ActionLink("Title", "Index", new { sortOrder = ViewBag.TitleSortParam, filter = ViewBag.CurrentFilter }) </th> <th> @Html.ActionLink("Isbn", "Index", new { sortOrder = ViewBag.IsbnSortParam, filter = ViewBag.CurrentFilter }) </th> <th> Summary </th> <th> @Html.ActionLink("Author", "Index", new { sortOrder = ViewBag.AuthorSortParam, filter = ViewBag.CurrentFilter }) </th> <th> Thumbnail </th> <th> @Html.ActionLink("Price", "Index", new { sortOrder = ViewBag.PriceSortParam, filter = ViewBag.CurrentFilter }) </th> <th> @Html.ActionLink("Published", "Index", new { sortOrder = ViewBag.PublishedSortParam, filter = ViewBag.CurrentFilter }) </th> <th></th> </tr> @foreach (var item in Model) { <tr> <td> @Html.DisplayFor(modelItem => item.Title) </td> <td> @Html.DisplayFor(modelItem => item.Isbn) </td> <td> @Html.DisplayFor(modelItem => item.Summary) </td> <td> @Html.DisplayFor(modelItem => item.Author) </td> <td> @Html.DisplayFor(modelItem => item.Thumbnail) </td> <td> @Html.DisplayFor(modelItem => item.Price) </td> <td> @Html.DisplayFor(modelItem => item.Published) </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> @Html.Partial("_Paging")
在之前我们创建的分页链接的分部视图中,也需要做这样的修改。在下面的代码中,四个分页链接中也需要传送当前页码、排序规则和筛选器选项:
<p> @if (Model.HasPreviousPage) { @Html.ActionLink("<< First", "Index", new { page = 1, sortOrder = ViewBag.CurrentSortOrder, filter = ViewBag.CurrentFilter }) @Html.Raw(" "); @Html.ActionLink("< Prev", "Index", new { page = Model.PageNumber - 1, sortOrder = ViewBag.CurrentSortOrder, filter = ViewBag.CurrentFilter }) } else { @:<< First @Html.Raw(" "); @:< Prev } @if (Model.HasNextPage) { @Html.ActionLink("Next >", "Index", new { page = Model.PageNumber + 1, sortOrder = ViewBag.CurrentSortOrder, filter = ViewBag.CurrentFilter }) @Html.Raw(" "); @Html.ActionLink("Last >>", "Index", new { page = Model.PageCount, sortOrder = ViewBag.CurrentSortOrder, filter = ViewBag.CurrentFilter }) } else { @:Next > @Html.Raw(" ") @:Last >> } </p>
接下来,再对BooksController中的Index()方法进行修改。接受一个新的筛选器变量,根据用户选择的筛选器,将会减少书籍列表的数量。有以下两种实现方式:
为Linq添加Where的字符串选择条件;
使用标准Linq的强类型选择条件。
由于通常筛选器通常不会包含太多条目,所以在这个秘诀中我们将使用第二种方法。使用第二种方法的时候,因为条目是预制的且是强类型的并不是动态的,所以不需要额外的输入检查或SQL注入防治。
using System; using System.Collections.Generic; using System.Data; using System.Data.Entity; using System.Linq; using System.Linq.Dynamic; using System.Web; using System.Web.Mvc; using MvcApplication4.Models; using MvcApplication4.Utils; using PagedList; namespace MvcApplication4.Controllers { public class BooksController : Controller { private BookDBContext db = new BookDBContext(); // // GET: /Books/ public ViewResult Index(string sortOrder, string filter, int page = 1) { #region ViewBag Resources ... #endregion #region ViewBag Sort Params ... #endregion var books = from b in db.Books select b; #region Filter Switch switch (filter) { case "NewReleases": var startDate = DateTime.Today.AddDays(-14); books = books.Where(b => b.Published <= DateTime.Today.Date && b.Published >= startDate ); break; case "ComingSoon": books = books.Where(b => b.Published > DateTime.Today.Date); break; default: // No filter needed break; } ViewBag.CurrentFilter = String.IsNullOrEmpty(filter) ? "" : filter; #endregion books = books.OrderBy(sortOrder); int maxRecords = 1; int currentPage = page - 1; return View(books.ToPagedList(currentPage, maxRecords)); } ... } }
在上面的例子中,用户可以筛选最新的内容并搜索返回今天或过去14天发布的书籍,又或者用户也可以选择即将发布并搜索返回任何今天出版的书籍。否则,没有选择任何筛选器就会返回所有书籍。
[b]参考[/b]
原书地址 书籍源代码
相关文章推荐
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十)[20 Recipes for Programming MVC 3]:通过关键字进行列表搜索
- [翻译]ASP.NET MVC 3 开发的20个秘诀(八)[20 Recipes for Programming MVC 3]:对列表进行分页
- [翻译]ASP.NET MVC 3 开发的20个秘诀(七)[20 Recipes for Programming MVC 3]:对列表进行排序
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十六)[20 Recipes for Programming MVC 3]:站点移动化
- [翻译]ASP.NET MVC 3 开发的20个秘诀(二)[20 Recipes for Programming MVC 3]:自动生成控制器和视图
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十八)[20 Recipes for Programming MVC 3]:自动完成搜索
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十九)[20 Recipes for Programming MVC 3]:路由用户至特定的Controller或Action
- [翻译]ASP.NET MVC 3 开发的20个秘诀(六)[20 Recipes for Programming MVC 3]:找回忘记的密码
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十二)[20 Recipes for Programming MVC 3]:缩放图片尺寸创建缩略图
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十三)[20 Recipes for Programming MVC 3]:实现Ajax增强用户体验
- [翻译]ASP.NET MVC 3 开发的20个秘诀(二十)[20 Recipes for Programming MVC 3]:缓存结果数据加速页面载入
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十一)[20 Recipes for Programming MVC 3]:通过表单上传文件
- [翻译]ASP.NET MVC 3 开发的20个秘诀(二十)[20 Recipes for Programming MVC 3]:缓存结果数据加速页面载入
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十五)[20 Recipes for Programming MVC 3]:启用图片验证码(CAPTCHA)
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十四)[20 Recipes for Programming MVC 3]:使用Ajax提交Form
- [翻译]ASP.NET MVC 3 开发的20个秘诀(一)[20 Recipes for Programming MVC 3]:通过密码验证限制访问视图
- [翻译]ASP.NET MVC 3 开发的20个秘诀(十七)[20 Recipes for Programming MVC 3]:卷帘式分页加载
- (转)[翻译]ASP.NET MVC 3 开发的20个秘诀(十八)[20 Recipes for Programming MVC 3]:自动完成搜索
- [翻译]ASP.NET MVC 3 开发的20个秘诀(三)[20 Recipes for Programming MVC 3]:验证用户输入
- [翻译]ASP.NET MVC 3 开发的20个秘诀(五)[20 Recipes for Programming MVC 3]:发送欢迎邮件