[转载][翻译]ASP.NET MVC 3 开发的20个秘诀(十)[20 Recipes for Programming MVC 3]:通过关键字进行列表搜索 – O2DS – 博客园.
议题
当排序、分页和筛选不能够帮助用户找到所需的内容,下一步最好的方法就是让用户输入他所想要查找的内容。
解决方案
使用Html.Helper创建表单和文本输入框,在筛选器选择结果的基础上用Linq Libary使用用户输入的关键字进行查询。
讨论
就像之前的秘诀所做的,添加关键字搜索需要修改Books和Index视图以及BooksController控制器。在视图中创建一个新的表单, 添加新的输入关键字的文本框。此外,为了在用户搜索关键字时,保持用户选择的排序、筛选器选项就需要重新编辑原有代码。下面是修改后的Book和 Index视图:
@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, Keyword = ViewBag.CurrentKeyword }) } else { @:All } | @if (ViewBag.CurrentFilter != "NewReleases") { @Html.ActionLink("New Releases", "Index", new { filter = "NewReleases", sortOrder = ViewBag.CurrentSortOrder, Keyword = ViewBag.CurrentKeyword }) } else { @:New Releases } | @if (ViewBag.CurrentFilter != "ComingSoon") { @Html.ActionLink("Coming Soon", "Index", new { filter = "ComingSoon", sortOrder = ViewBag.CurrentSortOrder, Keyword = ViewBag.CurrentKeyword }) } else { @:Coming Soon } </p> @using (Html.BeginForm()) { @:Search: @Html.TextBox("Keyword") <input type="submit" value="Search" /> } @Html.Partial("_Paging") <table> <tr> <th> @Html.ActionLink("Title", "Index", new { sortOrder = ViewBag.TitleSortParam, filter = ViewBag.CurrentFilter, Keyword = ViewBag.CurrentKeyword }) </th> <th> @Html.ActionLink("Isbn", "Index", new { sortOrder = ViewBag.IsbnSortParam, filter = ViewBag.CurrentFilter, Keyword = ViewBag.CurrentKeyword }) </th> <th> Summary </th> <th> @Html.ActionLink("Author", "Index", new { sortOrder = ViewBag.AuthorSortParam, filter = ViewBag.CurrentFilter, Keyword = ViewBag.CurrentKeyword }) </th> <th> Thumbnail </th> <th> @Html.ActionLink("Price", "Index", new { sortOrder = ViewBag.PriceSortParam, filter = ViewBag.CurrentFilter, Keyword = ViewBag.CurrentKeyword }) </th> <th> @Html.ActionLink("Published", "Index", new { sortOrder = ViewBag.PublishedSortParam, filter = ViewBag.CurrentFilter, Keyword = ViewBag.CurrentKeyword }) </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, Keyword = ViewBag.CurrentKeyword }) @Html.Raw(" "); @Html.ActionLink("< Prev", "Index", new { page = Model.PageNumber - 1, sortOrder = ViewBag.CurrentSortOrder, filter = ViewBag.CurrentFilter, Keyword = ViewBag.CurrentKeyword }) } else { @:<< First @Html.Raw(" "); @:< Prev } @if (Model.HasNextPage) { @Html.ActionLink("Next >", "Index", new { page = Model.PageNumber + 1, sortOrder = ViewBag.CurrentSortOrder, filter = ViewBag.CurrentFilter, Keyword = ViewBag.CurrentKeyword }) @Html.Raw(" "); @Html.ActionLink("Last >>", "Index", new { page = Model.PageCount, sortOrder = ViewBag.CurrentSortOrder, filter = ViewBag.CurrentFilter, Keyword = ViewBag.CurrentKeyword }) } else { @:Next > @Html.Raw(" ") @:Last >> } </p>
最后,需要修改BooksController控制器。在下面这个例子中,修改Index()方法,添加一个新的输入参数,可以接受用户输入关键字搜索书籍标题和作者。如果需要添加其他字段的搜索,只需要修改下面的例子,包含额外的字段:
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, string Keyword, int page = 1) { #region ViewBag Resources ... #endregion #region ViewBag Sort Params ... #endregion var books = from b in db.Books select b; #region Keyword Search if (!String.IsNullOrEmpty(Keyword)) { books = books.Where(b => b.Title.ToUpper().Contains(Keyword.ToUpper()) || b.Author.ToUpper().Contains( Keyword.ToUpper())); } ViewBag.CurrentKeyword = String.IsNullOrEmpty(Keyword) ? "" : Keyword; #endregion #region Filter Switch ... #endregion int maxRecords = 1; int currentPage = page - 1; return View(books.ToPagedList(currentPage, maxRecords)); } ... } }
参考