Welcome to Pete Brown's 10rem.net

First time here? If you are a developer or are interested in Microsoft tools and technology, please consider subscribing to the latest posts.

You may also be interested in my blog archives, the articles section, or some of my lab projects such as the C64 emulator written in Silverlight.

(hide this)

How to Retrieve and Process an RSS Feed in Silverlight 2

Pete Brown - 20 June 2008

For the Facebook Silverlight 2 Beta 2 application I'm writing, I need to be able to process a number of RSS feeds. In Silverlight 2 Beta 2, processing RSS is, well, really simple :)

Here's a class and associated event and exception classes I wrote to handle downloading the feed, and loading it into the RSS objects:

#region Support Classes (exception, eventargs)

public class FeedException : Exception
{
    public FeedException()
        : base("Exception retrieving or processing feed.")
    {
    }

    public FeedException(string message)
        : base("Exception retrieving or processing feed. " + message)
    {
    }

    public FeedException(string message, Exception innerException)
        : base("Exception retrieving or processing feed. " + message, 
                innerException)
    {
    }

}

public class FeedRetrievedEventArgs : EventArgs
{
    private SyndicationFeed _feed;

    public FeedRetrievedEventArgs(SyndicationFeed feed)
    {
        _feed = feed;
    }

    public SyndicationFeed Feed
    {
        get { return _feed; }
    }

}

public class FeedErrorEventArgs : EventArgs
{
    private Exception _exception;

    public FeedErrorEventArgs(Exception exception)
    {
        _exception = exception;
    }

    public Exception Error
    {
        get { return _exception; }
    }

}

#endregion

public class RssFeedGrabber
{
    public event EventHandler<FeedRetrievedEventArgs> FeedRetrieved;
    public event EventHandler<FeedErrorEventArgs> FeedError;

    private const string _nullResultErrorMessage = 
        "The returned stream was null. "+
        "The site may not have a valid client access policy in place.";
    private const string _parseErrorMessage = 
        "Unable to parse feed.";

    /// <summary>
    /// Makes an async call to return the feed data
    /// </summary>
    /// <param name="url">URL of the feed</param>
    public void RetrieveFeedAsync(Uri url)
    {
        WebClient client = new WebClient();

        client.OpenReadCompleted +=
            new OpenReadCompletedEventHandler(client_OpenReadCompleted);

        client.Encoding = System.Text.Encoding.UTF8;
        client.OpenReadAsync(url);
    }


    /// <summary>
    /// Event handler called when the WebClient returns the data from the call
    /// </summary>
    private void client_OpenReadCompleted(object sender, 
        OpenReadCompletedEventArgs e)
    {
        // process the feed

        if (e.Error == null && e.Result != null)
        {
            using (XmlReader reader = XmlReader.Create(e.Result))
            {
                try
                {
                    SyndicationFeed feed = SyndicationFeed.Load(reader);

                    FeedRetrievedEventArgs args = 
                        new FeedRetrievedEventArgs(feed);

                    OnFeedRetrieved(args);
                }
                catch (Exception ex)
                {
                    // the loader couldn't load the feed
                    FeedErrorEventArgs args = 
                        new FeedErrorEventArgs(
                            new FeedException(_parseErrorMessage, ex));
                    OnFeedError(args);
                }
            }
        }
        else
        {
            if (e.Error != null)
            {
                // there was an error returned from the call
                FeedErrorEventArgs args = new FeedErrorEventArgs(e.Error);
                OnFeedError(args);
            }
            else
            {
                // an empty stream. You get this silent failure when there 
                // is no crossdomain file in place (at least in beta2)
                FeedErrorEventArgs args = 
                    new FeedErrorEventArgs(
                        new FeedException(_nullResultErrorMessage));
                OnFeedError(args);
            }
        }
    }

    /// <summary>
    /// Internal method used to raise the feed event
    /// </summary>
    protected void OnFeedRetrieved(FeedRetrievedEventArgs args)
    {
        if (FeedRetrieved != null)
            FeedRetrieved(this, args);
    }

    /// <summary>
    /// Internal method used to raise the error event
    /// </summary>
    protected void OnFeedError(FeedErrorEventArgs args)
    {
        if (FeedError != null)
            FeedError(this, args);
    }

}

The class simply makes an async web call to retrieve the feed, then raises an event with the parsed feed. If you extend the feed formatter classes, you'll want to modify this code to use the appropriate one. If I end up extending anything, I'll write (and post) a templated version of this class.

Make sure you add a reference to System.ServiceModel.Syndication as well as add the appropriate using statement:

using System.ServiceModel.Syndication;

Keep in mind that the site hosting the rss feed will need to have an appropriate cross domain file in place, or you'll need to use a workaround like the ones described in Tim Heuer's blog post.

To use this class, simply call it from your code like this:

void Page_Loaded(object sender, RoutedEventArgs e)
{
    RssFeedGrabber grabber = new RssFeedGrabber();

    grabber.FeedRetrieved += 
        new EventHandler<FeedRetrievedEventArgs>(grabber_FeedRetrieved);
    grabber.FeedError += 
        new EventHandler<FeedErrorEventArgs>(grabber_FeedError);

    grabber.RetrieveFeedAsync(
        new Uri("http://feeds.feedburner.com/PeteBrown"));
}

void grabber_FeedError(object sender, FeedErrorEventArgs e)
{
    // there was an error with the feed. display appropriate
    // message or take action here
}

void grabber_FeedRetrieved(object sender, FeedRetrievedEventArgs e)
{
    foreach (SyndicationItem item in e.Feed.Items)
    {
        System.Diagnostics.Debug.WriteLine(item.Title.Text);
    }
}

(as an aside, I don't usually break up my code lines as seen above, unless the lines are extremely long; I broke them up just so they fit in this post.)

Let me know if you have any questions or run into any issues, or if you've come up with an even simpler/cooler/more functional version of this class.

   
posted by Pete Brown on Friday, June 20, 2008
filed under:    

7 comments for “How to Retrieve and Process an RSS Feed in Silverlight 2”

  1. d-n-c.netsays:
    Hello d-n-c.net http://d-n-c.net/images/michael-kors-pocketbook-New-W.html, I equitable wanted sichonduras.hn http://sichonduras.hn/up/blog/michael-kors-baby-bag-Michae.html to mention, I cojeco.org http://cojeco.org/blog/discount-michael-kors-purses-Wom.html different Your post www.kiteschule.de http://www.kiteschule.de/images/news_pics/michael-kors-shorts-Michael-.html doesn't acquaint any www.veurleste.be http://www.veurleste.be/userfiles/media/designer-bags-on-sale-Womens.html sense.
  2. www.afcel.frsays:
    What's up,equitable wanted www.afcel.fr http://www.afcel.fr/upload/image/discounted-michael-kors-Womens-Ch.html apt mention, www.dash.co.th http://www.dash.co.th/uploads/blog/michael-kors-perfume-review-Wo.htmlI loved this treatise It was sandiegoemploymentlaw.org http://sandiegoemploymentlaw.org/_admin/lib/fckeditor/uploads/media/cheap-michael-kors-watches-Wome.html practical. Keep www.gnet.ir http://www.gnet.ir/userfiles/michael-kors-brookville-Michae.html on posting!www.katesheridan.com http://www.katesheridan.com/images/designer-bags-online-Michael-Kor.html
  3. www.centrocultural.crsays:
    What's up,impartial wanted www.centrocultural.cr http://www.centrocultural.cr/admin/blog/michael-kors-aftershave-Micha.html to mention, web2.ntcu.edu.tw http://web2.ntcu.edu.tw/201411117webfile/blog/s-La.htmlI loved this treatise It was www.tourdesundarbans.com http://www.tourdesundarbans.com/UserFiles/bags-for-sale-Womens-Designer.html practical. Keep spic.by http://spic.by/blog/michael-kors-usa-online-store-.html aboard posting!henkelproductselector.noza.phdlabs.net http://henkelproductselector.noza.phdlabs.net/admin/fckimages/cmsimagesblack-leather-handbags-New-Wo.html

Comment on this Post

Remember me

4 trackbacks for “How to Retrieve and Process an RSS Feed in Silverlight 2”

  1. How to Retrieve and Process an RSS Feed in Silverlight 2 | Silverlight Guidesays:
    PingBack from http://www.silverlightguide.com/tutorials/how-to-retrieve-and-process-an-rss-feed-in-silverlight-2
  2. Community Blogssays:
    Michael Washington's Silverlight Desktop, Peter Bromberg on Data, Jesse Liberty on new interface
  3. Christopher Steensays:
    ASP.NET Why would you want to write your own WYSIWYG editor? [Via: JoeStagner ] AJAX Extender for TinyMCE...