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

Tagged as

Reading RSS items on Windows Phone 7

, 3 Feb 2011 Ms-PL
Rate this:
Please Sign up or sign in to vote.
Following is a utility class I wrote to help me read RSS items asynchronously on a Silverlight for 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 read RSS? Add Help

Following is a utility class I wrote to help me read RSS items asynchronously on a Silverlight for 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 read RSS?

Add Helper Assembly

The first thing we need to do is to add a reference to the assembly, System.ServiceModel.Syndication.dll which contains classes that can parse RSS feeds.

This assembly is part of the Silverlight 3 SDK. It isn’t part of the Windows Phone 7 SDK, but there is no problem in using it there. You can find the file under: %ProgramFiles%\Microsoft SDKs\Silverlight\v3.0\Libraries\Client\System.ServiceModel.Syndication.dll

Add Reference dialog

You will get the following warning, just ignore it, it works.

Adding a reference to a Silverlight assembly may lead to unexpected application behavior. Do you want to continue?

Define RssItem

Before we get to business, let’s define a model class that will encapsulate the data of a single RSS item.

Our RssItem class will hold the following properties: Title, Summary, PublishedDate and Url. In addition I provide a PlainSummary property that will hold a plain text version of the RSS item. Usually the summary has HTML tags that we just want to ignore, thus PlainSummary for the rescue.

/// <span class="code-SummaryComment"><summary>
</span>/// Model for RSS item
/// <span class="code-SummaryComment"></summary>
</span>public class RssItem
{
    /// <span class="code-SummaryComment"><summary>
</span>    /// Initializes a new instance of the <span class="code-SummaryComment"><see cref="RssItem"/> 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="summary">The summary.</param>
</span>    /// <span class="code-SummaryComment"><param name="publishedDate">The published date.</param>
</span>    /// <span class="code-SummaryComment"><param name="url">The URL.</param>
</span>    public RssItem(string title, string summary, string publishedDate, string url)
    {
        Title = title;
        Summary = summary;
        PublishedDate = publishedDate;
        Url = url;

        // Get plain text from html
        PlainSummary = HttpUtility.HtmlDecode(Regex.Replace(summary, "<[^>]+?>", ""));
    }

    /// <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 summary.
    /// <span class="code-SummaryComment"></summary>
</span>    /// <span class="code-SummaryComment"><value>The summary.</value>
</span>    public string Summary { get; set; }

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

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

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

Implement The RSS service

The RSS service will get the RSS feed URL as a parameter. In addition, since we want our class to work asynchronously we will accept as parameters a few more delegates:

  • Action<IEnumerable<RssItem>> onGetRssItemsCompleted, which will be called when the RSS items are ready to be processed.
  • Action<Exception> onError, which will be called if there is an error while getting the RSS items.
  • Action onFinally, which will be called always, whether there was an exception or not. Think of it as the finally section a common try-catch block.

So the method signature will be:

public static void GetRssItems(string rssFeed, 
    Action<IEnumerable<RssItem>> onGetRssItemsCompleted = null, 
    Action<Exception> onError = null, Action onFinally = null)

To get the feed XML we will use the WebClient class:

WebClient webClient = new WebClient();

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

webClient.OpenReadAsync(new Uri(rssFeed));

The actual RSS parsing is done using the SyndicationFeed class from our helper assembly:

// convert rss result to model
List<RssItem> rssItems = new List<RssItem>();
Stream stream = e.Result;
XmlReader response = XmlReader.Create(stream);
SyndicationFeed feeds = SyndicationFeed.Load(response);
foreach (SyndicationItem f in feeds.Items)
{
    RssItem rssItem = new RssItem(f.Title.Text, f.Summary.Text, f.PublishDate.ToString(), 
        f.Links[0].Uri.AbsoluteUri);
    rssItems.Add(rssItem);
}

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

/// <span class="code-SummaryComment"><summary>
</span>/// Gets the RSS items.
/// <span class="code-SummaryComment"></summary>
</span>/// <span class="code-SummaryComment"><param name="rssFeed">The RSS feed.</param>
</span>/// <span class="code-SummaryComment"><param name="onGetRssItemsCompleted">The on get RSS items completed.</param>
</span>/// <span class="code-SummaryComment"><param name="onError">The on error.</param>
</span>public static void GetRssItems(string rssFeed, 
    Action<IEnumerable<RssItem>> onGetRssItemsCompleted = null, 
    Action<Exception> onError = null, Action onFinally = null)
{
    WebClient webClient = new WebClient();

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

            // convert rss result to model
            List<RssItem> rssItems = new List<RssItem>();
            Stream stream = e.Result;
            XmlReader response = XmlReader.Create(stream);
            SyndicationFeed feeds = SyndicationFeed.Load(response);
            foreach (SyndicationItem f in feeds.Items)
            {
                RssItem rssItem = new RssItem(f.Title.Text, f.Summary.Text, 
                    f.PublishDate.ToString(), f.Links[0].Uri.AbsoluteUri);
                rssItems.Add(rssItem);
            }

            // notify completed callback
            if (onGetRssItemsCompleted != null)
            {
                onGetRssItemsCompleted(rssItems);
            }
        }
        finally
        {
            // notify finally callback
            if (onFinally != null)
            {
                onFinally();
            }
        }
    };

    webClient.OpenReadAsync(new Uri(rssFeed));
}

Using the RSS Service

Using the class is very easy, just provide the URL as the first parameter and a delegate for getting the “completed” notification.

private void Button_Click(object sender, RoutedEventArgs e)
{
    RssService.GetRssItems(
        WindowsPhoneBlogPosts,
        (items) => { listbox.ItemsSource = items; },
        (exception) => { MessageBox.Show(exception.Message); },
        null
        );
}

There is a sample application which can be downloaded here.

image

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

 
QuestionHow to open feed item link in the phone browser PinmemberMember 379033926-Dec-12 0:17 
QuestionDateTime problem Pinmembermikeluo200516-Dec-11 10:09 
GeneralUrl PinmemberCristiMirt21-Mar-11 0:39 
GeneralRe: Url PinmvpArik Poznanski21-Mar-11 0:55 
GeneralRe: Url PinmemberRanjan.D14-Dec-12 7:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.1411023.1 | Last Updated 3 Feb 2011
Article Copyright 2011 by Arik Poznanski
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid