在您的 ASP.NET MVC 应用程序中实现搜索功能






4.27/5 (12投票s)
本文将演示如何在应用程序中启用搜索。 ASP.NET MVC 框架更容易模块化和组件化您的设计/代码,这使得它能够以最小的努力获得更好的效果。
引言
如果您正在阅读这篇文章,那么很可能您与企业应用程序世界有所关联。 那么您的应用程序很可能以某种形式或另一种形式为用户提供搜索功能。 我们可能已经从过滤器/参数迁移到自由格式的无处不在的搜索,但需求仍然存在。
在我最近的一个项目中,我也有类似的需求——用户想要一种自由格式的“必应”式搜索,它可以在整个应用程序中一致且非常快速地工作。
虽然我可以采取多种方式来实现,但我们采取的方法是设计一个可重用的搜索骨架设计,任何使用 ASP.NET MVC 框架创建 Web 应用程序的人都可以轻松地集成它,并以最小的努力为其应用程序启用搜索功能。
我将使用一个示例联系人管理应用程序来演示如何编写一个骨架,该骨架允许轻松地将搜索功能集成到您的 ASP.NET MVC 网站中。 在我深入代码之前,让我们先看看最终结果,这样您就能构想出我想要实现的目标。
最简单的方式是,您在文本框中输入要查找的搜索文本,从下拉列表中选择要使用的搜索类别,然后单击“搜索”图标。
搜索流程

搜索面板

当用户输入内容并单击搜索图标时,将执行 searchClick
方法。
function searchClick() {
var category = $("#searchList").val();
var searchText = $("#txtSearch").val();
var queryString = "SearchText=" + searchText + "&Category=" + category;
$.post("/Search/Search", queryString, callBackSearch, "_default");
}
通过使用 $.post
(我使用的是 jQuery),我们指向我的 Search 控制器的 Search 操作。 它还将允许我们传递查询字符串。 在 callBackSearch
函数中,我们将把返回的响应 HTML 嵌入到当前页面中。
$('#SearchResult').html(responseText);
搜索控制器
public ActionResult Search(RouteInfo routeValues)
{
string actionName = "Search";
string controllerName =
SearchHelper.GetControllerName(routeValues.Category);
return RedirectToAction(actionName, controllerName, routeValues);
}
SearchHelper.GetControllerName
将返回负责给定类别的搜索结果视图的控制器名称。
public static string GetControllerName(string category)
{
// TODO: Manage thru configuration
return "Contact";
}
出于演示目的,我返回一个硬编码字符串“Contact
”。 在实际场景中,您可能需要为不同的类别搜索保留一些控制器配置。 请根据需要进行更改。
Search
控制器现在将重定向到特定的控制器搜索操作。 在这种情况下,它将调用 Contact
控制器。
联系人控制器
public ActionResult Search(RouteInfo routeValues,
SearchCriteriaSubController searchCriteria)
{
ContactManagerEntities _entitities = new ContactManagerEntities();
string criteria = SearchHelper.GetSqlCriteria(routeValues.SearchText,
routeValues.Category);
List<contact> contactList = _entitities.GetContacts(criteria).ToList();
ViewData["contactList"] = contactList;
return View();
}
Contact
控制器负责创建搜索结果视图。 要获取给定搜索文本的数据,我们需要创建一个名为 GetContacts
的存储过程。
ALTER PROCEDURE dbo.GetContacts
(
@criteria NVARCHAR(3000)
)
AS
SET NOCOUNT ON
DECLARE @SQLString NVARCHAR(4000);
SET @SQLString = N'SELECT ID, FirstName, LastName, Phone, Email
FROM Contacts WHERE ' + @criteria ;
EXECUTE sp_executesql @SQLString
RETURN
如果您的用户在搜索文本中输入“Microsoft”,那么将传递给此存储过程的条件将是
“[FirstName] LIKE '%microsoft%' OR [LastName] LIKE '%microsoft%'
OR [Email] LIKE '%microsoft%' “
注意:您可以维护自己的一组 SQL 符号格式(LIKE
、IN
、BETWEEN
、=
、>
、<
等)。 在此演示中,我使用了包含搜索功能。 您还可以扩展此搜索助手类以允许用户进行全文搜索。 单击以下链接以了解如何为 SQL Server 的全文搜索 CONTAINS
谓词语法创建类似 Google 的查询。
SQL 条件生成器
public static string GetSqlCriteria(string searchText, string category)
{
StringBuilder sb = new StringBuilder();
// Get the list of columns for this category
List<searchcolumn> SearchColumns = GetSearchColumns(category);
bool isFirstRow = true;
foreach (SearchColumn row in SearchColumns)
{
string text;
// Build the SQL syntax for this column
// eg. [FirstName] LIKE '%microsoft%'
text = string.Format(row.SymbolFormat, row.ColumnName, searchText);
if (isFirstRow)
isFirstRow = false;
else
sb.Append(" OR ");
sb.Append(text);
}
return sb.ToString();
}
一旦 SQL 条件准备就绪,contact
控制器将将其传递给 dbEntitities GetContacts
方法以获取搜索结果。
List<contact> contactList = _entitities.GetContacts(criteria).ToList();
结果视图

使用子控制器显示搜索条件
由于我们的搜索条件 UI 对于每个类别搜索结果都是通用的,因此我想在其他页面上重用条件 UI 部分。 我使用了子控制器的操作来在结果视图页面中呈现搜索条件 UI。
SubController
派生自 Controller
并实现 ISubController
接口。 但它是一个控制器,所以:
- 它有自己的视图。
- 它有 ViewData。
- 它可以访问查询字符串和其他控制器上下文。
您可以在 MvcContrib 的 SubController 上下载并探索一个完整的可用示例。
列出 SearchCriteriaSubController.cs
public ViewResult SearchCriteria(RouteInfo routeValues)
{
ViewData["text"] = "SearchText = " + routeValues.SearchText +
" and Category = " + routeValues.Category;
return View();
}
列出 SearchCriteria.ascx

摘要
因此,重申一下,您将遵循以下步骤来为任何其他应用程序启用搜索功能
- 创建搜索控制器
- 创建搜索存储过程
- 设置必要的更改以从搜索控制器重定向路由
- 创建结果视图
结论
我的目标是演示在应用程序中启用搜索是多么简单直接。 ASP.NET MVC 框架使设计/代码的模块化和组件化更加容易,这使其成为 Windows 网络应用程序的平台首选。
我们创建了一个可用的示例应用程序,概述了搜索需求,创建了一个实现了搜索功能的重用骨架项目,并展示了如何在您的应用程序中将其连接起来以启用搜索功能。
就是这样。 对于那些不熟悉 ASP.NET MVC 和 Entity Framework 的人来说,代码一开始可能会显得有些混乱,但一旦您对其进行一些操作并查看一些示例,我相信您就会掌握它。 对于问题/疑虑,如果您能在博客上发表评论,我们将不胜感激。