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

在 Windows Phone 7 上搜索 Digg

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2011年2月10日

Ms-PL

2分钟阅读

viewsIcon

12230

我编写的另一个辅助类,用于在 Windows Phone 7 应用程序中异步搜索 Digg 结果

以下是 另一个我编写的实用类,用于帮助我在 Windows Phone 7 应用程序中异步搜索 Digg 的结果。

我将展示它是如何编写的,以及如何使用它。 在本文末尾,您可以找到一个包含所有代码的示例应用程序。

digg search sample

如何搜索 Digg?

定义 DiggStory

首先,我们定义一个模型类来保存单个 Digg 条目。 该类将具有以下属性:

  • Title – Digg 条目的标题
  • Description – Digg 条目的描述
  • Link – Digg 条目的链接
  • Diggs – Digg 中的点赞数
/// <summary>
/// Model for Digg Story
/// </summary>
public class DiggStory
{
    /// <summary>
    /// Initializes a new instance of the <see cref="DiggStory"/> class.
    /// </summary>
    /// <param name="title">The title.</param>
    /// <param name="description">The description.</param>
    /// <param name="link">The link.</param>
    /// <param name="diggs">The diggs.</param>
    public DiggStory(string title, string description, string link, int diggs)
    {
        Title = title;
        Description = description;
        Link = link;
        Diggs = diggs;
    }

    /// <summary>
    /// Gets or sets the title.
    /// </summary>
    /// <value>The title.</value>
    public string Title { get; set; }

    /// <summary>
    /// Gets or sets the description.
    /// </summary>
    /// <value>The description.</value>
    public string Description { get; set; }

    /// <summary>
    /// Gets or sets the link.
    /// </summary>
    /// <value>The link.</value>
    public string Link { get; set; }

    /// <summary>
    /// Gets or sets the diggs.
    /// </summary>
    /// <value>The diggs.</value>
    public int Diggs { get; set; }
}

添加程序集

在以下实现中,我使用 Digg 搜索 API,它返回基于 XML 的结果,因此我使用 LINQ to XML 来轻松解析输出。

为了做到这一点,我们将添加对程序集 System.Xml.Linq.dll 的引用。

add reference system.xml.linq

生成应用程序密钥

与大多数服务提供商一样,Digg 也要求您为您的应用程序生成一个应用程序密钥。 这有助于他们了解谁在使用他们的服务,并允许他们限制来自单个用户的请求。

我发现以下应用程序密钥可以工作,但我建议您在商业应用程序中找到一种生成新的方法。

private const string DiggApplicationKey = "http://www.myapp.com";

实现 Digg 搜索服务

查询 Digg 服务非常简单。 只需要使用以下链接:

其中 {0} 应该替换为您的搜索词,{1} 应该替换为您的应用程序密钥。

因此,我们的 Search 方法将接收搜索词作为参数。 此外,由于我们希望我们的类异步工作,我们将接受更多委托作为参数:

  • Action<IEnumerable<DiggStory>> onSearchCompleted,当 Digg 结果准备好进行处理时将调用它。
  • Action<string, Exception> onError,如果在搜索 Digg 时发生错误将调用它。 委托的第一个参数是搜索词,第二个参数是异常。
  • Action onFinally,无论是否发生异常,都将始终调用它。 可以将其视为常见 try-catch 块中的 finally 部分。

因此,该方法签名将是

public static void Search(string searchText, 
    Action<IEnumerable<DiggStory>> onSearchCompleted = null, 
    Action<string, Exception> onError = null, Action onFinally = null)

要运行搜索,我们将使用 WebClient

WebClient webClient = new WebClient();

// register on download complete event
webClient.DownloadStringCompleted += delegate(object sender, 
    DownloadStringCompletedEventArgs e)
{
    ...
};

// start search
webClient.DownloadStringAsync(new Uri(string.Format(DiggSearchQuery, 
    searchText, DiggApplicationKey)));

其中 DiggSearchQuery 定义如下

private const string DiggSearchQuery = 
    "http://services.digg.com/search/stories?query={0}&appkey={1}";

搜索结果是一个 XML string,因此我们使用 LINQ to XML 来解析它

// convert xml result to model
XElement storyXml = XElement.Parse(e.Result);

var stories = from story in storyXml.Descendants("story")
              select new DiggStory(
                  story.Element("title").Value,
                  story.Element("description").Value,
                  story.Attribute("link").Value,
                  int.Parse(story.Attribute("diggs").Value));

其余代码处理不同的委托:onCompletedonErroronFinally。 我在此完整地提供该方法

/// <summary>
/// Searches the specified search text.
/// </summary>
/// <param name="searchText">The search text.</param>
/// <param name="onSearchCompleted">The on search completed.</param>
/// <param name="onError">The on error.</param>
public static void Search(string searchText, 
    Action<IEnumerable<DiggStory>> onSearchCompleted = null, 
    Action<string, Exception> onError = null, Action onFinally = null)
{
    WebClient webClient = new WebClient();

    // register on download complete event
    webClient.DownloadStringCompleted += delegate(object sender, 
        DownloadStringCompletedEventArgs e)
    {
        try
        {
            // report error
            if (e.Error != null)
            {
                if (onError != null)
                {
                    onError(searchText, e.Error);
                }
                return;
            }

            // convert xml result to model
            XElement storyXml = XElement.Parse(e.Result);

            var stories = from story in storyXml.Descendants("story")
                            select new DiggStory(
                                story.Element("title").Value,
                                story.Element("description").Value,
                                story.Attribute("link").Value,
                                int.Parse(story.Attribute("diggs").Value));

            // notify completed callback
            if (onSearchCompleted != null)
            {
                onSearchCompleted(stories);
            }
        }
        finally
        {
            // notify finally callback
            if (onFinally != null)
            {
                onFinally();
            }
        }
    };

    // start search
    webClient.DownloadStringAsync(new Uri(string.Format(DiggSearchQuery, 
        searchText, DiggApplicationKey)));
}

使用 Digg 搜索服务

使用该类非常简单,只需传递所需的搜索词和“完成”通知的委托即可。

DiggService.Search(
    textbox.Text,
    (items) => { listbox.ItemsSource = items; },
    (s, exception) => { MessageBox.Show("Search term " + s + 
        " could not be found due to:\n" + exception.Message); },
    null
    );

有一个示例应用程序可以从 这里 下载。

注意:此代码最初作为 Microsoft 为我编写的 Windows Phone 开发者培训工具包 中“使用 Pivot 和 Panorama 控件”实验室的一部分发布。

暂时就到这里,
Arik Poznanski

© . All rights reserved.