65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.50/5 (6投票s)

2007 年 11 月 13 日

CPOL

3分钟阅读

viewsIcon

49368

downloadIcon

438

此应用程序会将 Windows Live Search Web 服务的搜索结果绑定到 GridView 控件,并利用 AJAX 1.0 进行搜索和分页。

Screenshot - search.jpg

引言

此应用程序会将 Windows Live Search Web 服务的搜索结果绑定到 GridView 控件,并利用 AJAX 1.0 进行搜索和分页。此应用程序允许您一次搜索多个网站。一个实际示例可以在 这里找到。然而,城市示例不像本文中的示例那样是 AJAX 驱动的。

您可以通过 web.config 文件自定义搜索属性。在继续之前,请确保满足以下要求。

  1. 已安装 ASP.NET 2.0。
  2. 在 IIS 中设置下载的应用程序,并选择 ASP.NET 2.0。
  3. 您的计算机上已安装 AJAX 1.0。
  4. 从 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; }
    }
}

在构造函数中,属性被填充。SPWindowsLiveSearch 的本地属性,类型为 LiveSearchProperties。在此,配置设置存储在一个新的 LiveSearchProperties 实例中,然后存储在 SPWindowsLiveSearch 属性)中。

/// <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 类,该类利用两个主要类:SearchRequestSearchResponseSearchRequest 对象包含允许 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("&#57344;", "<strong>").Replace("&#57345;", "</strong>");
      row.Description = AntiXss.HtmlEncode(CheckForNull(response_result.Description))
          .Replace("&#57344;", "<strong>").Replace("&#57345;", "</strong>");
      row.DisplayURL = AntiXss.HtmlEncode(CheckForNull(response_result.DisplayUrl))
          .Replace("&#57344;", "<strong>").Replace("&#57345;", "</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 事件用于获取总结果数。考虑到 GridViewCount 属性仅给出屏幕上实际显示的结果数量,这是我所知的唯一方法。

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 中的可选功能)
    • 修复了字段空引用错误
    • 添加了搜索
    • 提供了“无结果”消息
© . All rights reserved.