Click here to Skip to main content
Click here to Skip to main content
Technical Blog

Tagged as

Search Digg on Windows Phone 7

, 10 Feb 2011 Ms-PL
Rate this:
Please Sign up or sign in to vote.
Following is another utility class I wrote to help me search Digg results asynchronously on a Windows Phone 7 application. I will present how it was written and then how to use it. At the end of this post you can find a sample application that contains all the code. How to Search Digg? Define D

Following is another utility class I wrote to help me search Digg results asynchronously on a Windows Phone 7 application.

I will present how it was written and then how to use it. At the end of this post you can find a sample application that contains all the code.

digg search sample

How to Search Digg?

Define DiggStory

First we define a model class that will hold a single Digg entry. This class will have the following properties:

  • Title – title of the Digg entry
  • Description – description of the Digg entry
  • Link – link to the Digg entry
  • Diggs – number of diggs in Digg
/// <span class="code-SummaryComment"><summary>
</span>/// Model for Digg Story
/// <span class="code-SummaryComment"></summary>
</span>public class DiggStory
{
    /// <span class="code-SummaryComment"><summary>
</span>    /// Initializes a new instance of the <span class="code-SummaryComment"><see cref="DiggStory"/> class.
</span>    /// <span class="code-SummaryComment"></summary>
</span>    /// <span class="code-SummaryComment"><param name="title">The title.</param>
</span>    /// <span class="code-SummaryComment"><param name="description">The description.</param>
</span>    /// <span class="code-SummaryComment"><param name="link">The link.</param>
</span>    /// <span class="code-SummaryComment"><param name="diggs">The diggs.</param>
</span>    public DiggStory(string title, string description, string link, int diggs)
    {
        Title = title;
        Description = description;
        Link = link;
        Diggs = diggs;
    }

    /// <span class="code-SummaryComment"><summary>
</span>    /// Gets or sets the title.
    /// <span class="code-SummaryComment"></summary>
</span>    /// <span class="code-SummaryComment"><value>The title.</value>
</span>    public string Title { get; set; }

    /// <span class="code-SummaryComment"><summary>
</span>    /// Gets or sets the description.
    /// <span class="code-SummaryComment"></summary>
</span>    /// <span class="code-SummaryComment"><value>The description.</value>
</span>    public string Description { get; set; }

    /// <span class="code-SummaryComment"><summary>
</span>    /// Gets or sets the link.
    /// <span class="code-SummaryComment"></summary>
</span>    /// <span class="code-SummaryComment"><value>The link.</value>
</span>    public string Link { get; set; }

    /// <span class="code-SummaryComment"><summary>
</span>    /// Gets or sets the diggs.
    /// <span class="code-SummaryComment"></summary>
</span>    /// <span class="code-SummaryComment"><value>The diggs.</value>
</span>    public int Diggs { get; set; }
}

Add Assembly

In the following implementation I use Digg Search API which returns XML based results, so I‘m using LINQ to XML to easily parse the output.

In order to do so, we will add a reference to the assembly System.Xml.Linq.dll

add reference system.xml.linq

Generate Application Key

Like most service providers, Digg also requires you to generate an application key for your application. This helps them know who uses their service and allow them to limit the requests from a single consumer.

I found the following application key to work, but I suggest you find a way to generate a new one in commercial apps.

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

Implement the Digg Search Service

Querying the Digg service is rather easy. Just use the following link:

http://services.digg.com/search/stories?query={0}&appkey={1}

Where {0} should be replaced with your search term and {1} should be replace with your application key.

So our Search method will receive the search term as a parameter. In addition, since we want our class to work asynchronously we will accept as parameters a few more delegates:

  • Action<IEnumerable<DiggStory>> onSearchCompleted, which will be called when the Digg results are ready to be processed.
  • Action<string, Exception> onError, which will be called if there is an error while searching Digg. The first parameter for the delegate is the search term and the second is the exception.
  • Action onFinally, which will be called always, whether there was an exception or not. Think of it as the finally section on a common try-catch block.

So the method signature will be:

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

To run the search we will use the WebClient class:

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)));

where DiggSearchQuery is defined as follows:

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

The result of the search is an XML string, so we use LINQ to XML to parse it:

// 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));

The rest of the code handles the different delegates: onCompleted, onError, onFinally. I bring here the method in its full:

/// <span class="code-SummaryComment"><summary>
</span>/// Searches the specified search text.
/// <span class="code-SummaryComment"></summary>
</span>/// <span class="code-SummaryComment"><param name="searchText">The search text.</param>
</span>/// <span class="code-SummaryComment"><param name="onSearchCompleted">The on search completed.</param>
</span>/// <span class="code-SummaryComment"><param name="onError">The on error.</param>
</span>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)));
}

Using the Digg Search Service

Using the class is very easy, just pass the required search term and a delegate for the “completed” notification.

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
    );

There is a sample application which can be downloaded here.

Note: this code was first published as part of the “Using Pivot and Panorama Controls” lab found in the Windows Phone Training Kit for Developers, which I wrote for Microsoft.

That’s it for now, Arik Poznanski.

License

This article, along with any associated source code and files, is licensed under The Microsoft Public License (Ms-PL)

Share

About the Author

Arik Poznanski
Software Developer (Senior) Verint
Israel Israel
Arik Poznanski is a senior software developer at Verint. He completed two B.Sc. degrees in Mathematics & Computer Science, summa cum laude, from the Technion in Israel.
 
Arik has extensive knowledge and experience in many Microsoft technologies, including .NET with C#, WPF, Silverlight, WinForms, Interop, COM/ATL programming, C++ Win32 programming and reverse engineering (assembly, IL).
Follow on   Twitter   Google+

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.141223.1 | Last Updated 10 Feb 2011
Article Copyright 2011 by Arik Poznanski
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid