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 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
public class DiggStory
{
public DiggStory(string title, string description, string link, int diggs)
{
Title = title;
Description = description;
Link = link;
Diggs = diggs;
}
public string Title { get; set; }
public string Description { get; set; }
public string Link { get; set; }
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.
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 allows 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:
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();
webClient.DownloadStringCompleted += delegate(object sender,
DownloadStringCompletedEventArgs e)
{
...
};
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:
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:
public static void Search(string searchText,
Action<IEnumerable<DiggStory>> onSearchCompleted = null,
Action<string, Exception> onError = null, Action onFinally = null)
{
WebClient webClient = new WebClient();
webClient.DownloadStringCompleted += delegate(object sender,
DownloadStringCompletedEventArgs e)
{
try
{
if (e.Error != null)
{
if (onError != null)
{
onError(searchText, e.Error);
}
return;
}
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));
if (onSearchCompleted != null)
{
onSearchCompleted(stories);
}
}
finally
{
if (onFinally != null)
{
onFinally();
}
}
};
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