[翻译]ASP.NET MVC 3 开发的20个秘诀(十)[20 Recipes for Programming MVC 3]:通过关键字进行列表搜索
议题
当排序、分页和筛选不能够帮助用户找到所需的内容,下一步最好的方法就是让用户输入他所想要查找的内容。
解决方案
使用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));
}
...
}
}
参考