使用 ASP.NET 和 AJAX 1.0 消费 Windows Live Search Web 服务






4.50/5 (6投票s)
此应用程序会将 Windows Live Search Web 服务的搜索结果绑定到 GridView 控件,并利用 AJAX 1.0 进行搜索和分页。
引言
此应用程序会将 Windows Live Search Web 服务的搜索结果绑定到 GridView
控件,并利用 AJAX 1.0 进行搜索和分页。此应用程序允许您一次搜索多个网站。一个实际示例可以在 这里找到。然而,城市示例不像本文中的示例那样是 AJAX 驱动的。
您可以通过 web.config 文件自定义搜索属性。在继续之前,请确保满足以下要求。
- 已安装 ASP.NET 2.0。
- 在 IIS 中设置下载的应用程序,并选择 ASP.NET 2.0。
- 您的计算机上已安装 AJAX 1.0。
- 从 MS 获取用于此 Web 服务的密钥(MSN)。然后,您可以将密钥添加到 web.config 中的应用程序设置。
背景
我在网上找到了一些零散的示例,但都没有实质性的帮助。我认为这可能对那些希望看到工作示例的人有帮助。您总可以移除 AJAX,并通过查询字符串捕获搜索查询,只需进行一些小的更改。
使用代码
WindowsLiveSearch
类有一个名为 Search
的主要方法。实例化该类将在 web.config 中填充所需的属性,以便在 Search
方法中使用。
主要配置属性被组织为一个名为 LiveSearchProperties
的类型。
/// <summary>
/// Properties used for setting up web service
/// </summary>
public class LiveSearchProperties
{
private string _searchLic;
public string SearchLic
{
get { return _searchLic; }
set { _searchLic = value; }
}
private int _resultsSize;
public int ResultsSize
{
get { return _resultsSize; }
set { _resultsSize = value; }
}
private string _searchSites;
public string SearchSites
{
get { return _searchSites; }
set { _searchSites = value; }
}
private SafeSearchOptions _searchOptions;
public SafeSearchOptions SearchOptions
{
get { return _searchOptions; }
set { _searchOptions = value; }
}
}
在构造函数中,属性被填充。SP
是 WindowsLiveSearch
的本地属性,类型为 LiveSearchProperties
。在此,配置设置存储在一个新的 LiveSearchProperties
实例中,然后存储在 SP
(WindowsLiveSearch
属性)中。
/// <summary>
/// Creates a WindowsLiveSearch and fills properties with values
/// </summary>
public WindowsLiveSearch()
{
// -------------------------------
// Initialize properties
// -------------------------------
// Error Property
ErrorMsg = "";
// LiveSearchProperties
LiveSearchProperties sp = new LiveSearchProperties();
sp.SearchLic = ConfigurationManager.AppSettings["SearchLic"];
sp.ResultsSize = Int32.Parse(ConfigurationManager.AppSettings["ResultsSize"]);
sp.SearchSites = ConfigurationManager.AppSettings["SearchSites"];
sp.SearchOptions = SafeSearchOptions.Off;
SP = sp; // Save instance to class property
sp = null; // Null out unused object
}
Search
方法如下所示:
/// <summary>
/// This is the main function you call after object creation.
/// You can pass the search query in here and get a list of
/// results to work with. You can easily bind these results to an
/// ASP.NET control if desired or foreach the list to get the data.
/// </summary>
/// <param name="searchQuery">The search query</param>
/// <returns>A generic list of search results</returns>
public IList<LiveSearchResults> Search(string searchQuery)
{
// Basic checks
if ((searchQuery == null) ||
(searchQuery.Length == 0) ||
(searchQuery.Trim() == ""))
return null;
IList<LiveSearchResults> resultsCollection =
new List<LiveSearchResults>();
using (MSNSearchService s = new MSNSearchService())
{
SearchRequest searchRequest = new SearchRequest();
searchRequest = SetUpRequest(searchRequest, searchQuery, SP);
SearchResponse searchResponse;
try
{
searchResponse = s.Search(searchRequest);
resultsCollection = CaptureResults(searchResponse);
}
catch (Exception e)
{
ErrorMsg = e.ToString();
}
finally
{
// If there was an error
if (ErrorMsg.Length > 0)
LogMessage("There was an error with searchQuery: " +
searchQuery);
else
LogMessage("A successful search was made with searchQuery: " +
searchQuery);
}
}
return resultsCollection;
}
Search
方法使用 MSNSearchService
类,该类利用两个主要类:SearchRequest
和 SearchResponse
。SearchRequest
对象包含允许 Search
类理解您要进行的搜索类型的所有必需属性。在此示例中,我们将进行网络搜索。
以下是 SearchRequest
方法:
/// <summary>
/// Sets up the MSN SearchRequest Object
/// </summary>
/// <param name="searchRequest">A SearchRequest Object</param>
/// <param name="searchQuery">The search query</param>
/// <param name="sp">LiveSearchProperties Object</param>
/// <returns>The SearchRequest Object</returns>
private SearchRequest SetUpRequest(
SearchRequest searchRequest,
string searchQuery,
LiveSearchProperties sp)
{
SourceRequest[] sr = new SourceRequest[1];
sr[0] = new SourceRequest();
sr[0].Source = SourceType.Web;
sr[0].ResultFields = ResultFieldMask.All;
sr[0].Count = sp.ResultsSize;
sr[0].Offset = 0;
searchRequest.Requests = sr;
searchRequest.Query = searchQuery + " " + sp.SearchSites;
searchRequest.SafeSearch = sp.SearchOptions;
searchRequest.AppID = sp.SearchLic;
searchRequest.Flags = SearchFlags.MarkQueryWords;
searchRequest.CultureInfo = "en-US";
return searchRequest;
}
设置请求后,您可以使用 Web 服务获取 SearchResponse
。我创建了一个名为 CaptureResults
的方法来执行此操作。为了存储捕获的结果,我创建了一个名为 LiveSearchResults
的类型。
LiveSearchResults
属性
/// <summary>
/// Properties used to store search results
/// </summary>
public class LiveSearchResults
{
private string _url;
public string URL
{
get { return _url; }
set { _url = value; }
}
private string _title;
public string Title
{
get { return _title; }
set { _title = value; }
}
private string _description;
public string Description
{
get { return _description; }
set { _description = value; }
}
private string _displayURL;
public string DisplayURL
{
get { return _displayURL; }
set { _displayURL = value; }
}
private string _cachedURL;
public string CachedURL
{
get { return _cachedURL; }
set { _cachedURL = value; }
}
}
这是 CaptureResults
方法:
/// <summary>
/// Creates a list of Search Results
/// </summary>
/// <param name="search_Response">The LiveSearch Response</param>
/// <returns>A collection of search results</returns>
private IList<LiveSearchResults> CaptureResults(SearchResponse search_Response)
{
// Create a collection object to build list
IList<LiveSearchResults> resultsCollector = new List<LiveSearchResults>();
//Get data from web service
foreach (SourceResponse response in search_Response.Responses)
{
Result[] response_results = null;
response_results = response.Results;
//Secure and store output
foreach (Result response_result in response_results)
{
LiveSearchResults row = new LiveSearchResults();
row.URL = AntiXss.HtmlEncode(CheckForNull(response_result.Url));
row.Title = AntiXss.HtmlEncode(CheckForNull(response_result.Title))
.Replace("", "<strong>").Replace("", "</strong>");
row.Description = AntiXss.HtmlEncode(CheckForNull(response_result.Description))
.Replace("", "<strong>").Replace("", "</strong>");
row.DisplayURL = AntiXss.HtmlEncode(CheckForNull(response_result.DisplayUrl))
.Replace("", "<strong>").Replace("", "</strong>");
row.CachedURL = AntiXss.HtmlEncode(CheckForNull(response_result.CacheUrl));
resultsCollector.Add(row);
}
}
return resultsCollector;
}
此方法使用 MS 的 AntiXssLibrary.dll。这将防止不需要的跨站点脚本数据存储在结果中。此方法生成一个通用列表并将其返回给 Search
方法,这将使您能够将结果绑定到 Web 控件。
表示层
ObjectDataSource
负责所有工作。
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="Search"
TypeName="Windows.Live.Search.WindowsLiveSearch" OnSelected="ObjectDataSource1_Selected">
<SelectParameters>
<asp:FormParameter FormField="searchBox" Name="searchQuery" Type="String" />
</SelectParameters>
</asp:ObjectDataSource>
如所示,您可以看到我在 TypeName
参数中包含了该类。然后,我从类中选择了 "Search
" 方法。
OnSelected
事件用于获取总结果数。考虑到 GridView
的 Count
属性仅给出屏幕上实际显示的结果数量,这是我所知的唯一方法。
OnSelected
方法
// Get the total number of records
protected void ObjectDataSource1_Selected(object sender,
ObjectDataSourceStatusEventArgs e)
{
Instructionlbl.Text = "";
try
{
IList<LiveSearchResults> resultsCollection =
new List<LiveSearchResults>();
resultsCollection = (IList<LiveSearchResults>)e.ReturnValue;
resultsTotal = resultsCollection.Count;
if (resultsTotal == 0)
Instructionlbl.Text = "Your search provided no results.";
}
catch (System.NullReferenceException)
{
Instructionlbl.Text = "Please enter a search term.";
}
}
如果搜索查询为空,则会出现 System.NullReferenceException
。因此,指令标签在此处用于要求用户“请输入搜索词”。
AJAX 相关内容
要使其工作,您必须将您希望更新的控件包含在 AJAX UpdatePanel
中。在此示例中,我将 GridView
控件和指令标签放入了 UpdatePanel
中。
要触发更新面板,只需提供以下内容:
<Triggers>
<asp:AsyncPostBackTrigger ControlID="SearchButton" EventName="click" />
</Triggers>
这只是说明在发生 Click 事件时触发更新面板。
关注点
您需要的所有内容都将在项目下载中。您应该能够利用我的工作并根据您的需求进行自定义。您可以在 web.config 文件中尝试搜索设置。您还可以更改默认的搜索网站。所有设置都与使用 Live 搜索引擎进行高级搜索时使用的设置相同。
历史
- 11/13/2007
- 将项目添加到 Code Project。
- 11/20/2007
- 添加了日志记录(web.config 中的可选功能)
- 修复了字段空引用错误
- 添加了搜索
- 提供了“无结果”消息