Annsa - Useful Code Resources

Consuming an RSS Feed in Silverlight with .Net 3.5 SyndicationFeed, Part 1

In a previous code sample we presented a simple method to consume an RSS feed using some features introduced in ASP.NET 2.0. In this sample we'll revisit the problem and present a solution that makes use of features introduced in .Net Framework 3.5 as well as Microsoft's Silverlight technology.

On the right of this page is the finished Silverlight control displaying the latest entries from the Google blog.

.Net Framework 3.5

.Net Framework 3.5 has extensive new features, and we'll make use of two in this sample; the System.ServiceModel.Syndication namespace and LINQ (Language-Integrated Query).

SyndicationFeed is a member of the System.ServiceModel.Syndication namespace and provides a strongly typed representation of an ATOM or RSS feed, and the items it contains. In our previous example we interrogated the raw XML of the feed to extract the information we needed to display. With .Net Framework 3.5, SyndicationFeed and the associated SyndicationItem encapsulate that process.

Silverlight

According to the blurb, "Microsoft Silverlight is a cross-browser, cross-platform implementation of the .NET Framework for building and delivering rich interactive applications (RIA) for the Web". This sample uses Silverlight 2 to illustrate delivering Silverlight content to a web page - including data binding (in this case to an RSS feed) and initialisation.

Reading the Feed

The core of the Silverlight control reads a specified RSS feed using the SyndicationFeed object mentioned. The code snippet below shows the ReedFeed function that starts the download of the feed. In Silverlight external downloads are always async. The DownloadCompleted function is called when the feed has been downloaded. It uses the SyndicationFeed object to load and parse the downloaded contents.

public void ReadFeed() { if (!string.IsNullOrEmpty(this.FeedUrl)) { WebClient client = new WebClient(); Uri uri = new Uri(this.FeedUrl); client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadCompleted); client.DownloadStringAsync(uri); } } void DownloadCompleted(object sender, DownloadStringCompletedEventArgs e) { if (!string.IsNullOrEmpty(e.Result)) { XmlReader feedReader = XmlReader.Create(new StringReader(e.Result)); SyndicationFeed feed = SyndicationFeed.Load(feedReader); rssList.ItemsSource = feed.Items.Take(this.FeedItemCount); } }

The code makes use of the LINQ Take method to extract the first n elements of the feed (based on a property value).

Databinding

The items read by the feed are bound to a Silverlight ItemsControl. A snippet of the relevant XAML is shown below.

<ItemsControl x:Name="rssList"> <ItemsControl.ItemTemplate> <DataTemplate> <StackPanel Margin="0 0 0 10"> <HyperlinkButton FontSize="12" TargetName="_blank" NavigateUri="{Binding FirstLink}"> <TextBlock Text="{Binding Title.Text}" TextWrapping="Wrap" /> </HyperlinkButton> <TextBlock Text="{Binding CleanedSummary}" FontSize="10" Margin="10 0 0 0" TextWrapping="Wrap" /> <TextBlock Text="{Binding FormattedPublishDate}" FontSize="10" HorizontalAlignment="Right" /> </StackPanel> </DataTemplate> </ItemsControl.ItemTemplate>

Handing Type Conversion

The XAML refers to Converter objects for most of the databinding definitions. Converters are used in Silverlight to convert source datatypes to a format suitable for the output. For example, the NavigateUri property of the Silverlight HyperlinkButton control expects a Uri - but the SyndicationItem has a Links property which is a collection of Uri objects. The Converter is used to extract the first Uri from the Links collection and return it. The converters are defined in the code behind of the XAML.

/// <summary> /// A Converter used to extract the first Uri from the /// the supplied list. /// </summary> public class LinkConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { // Get the first link - that's the link to the post return ((Collection<SyndicationLink>)value)[0].Uri; } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { throw new NotImplementedException(); } }

The XAML includes a reference to the converter to allow it to be used.

<UserControl.Resources> <custom:SummaryConverter x:Key="summaryConverter" /> <custom:LinkConverter x:Key="linkConverter"/> <custom:PublishDateConverter x:Key="publishDateConverter"/> </UserControl.Resources>

The custom namespace used in the XAML Resources section is defined as an attribute of the XAML UserControl element.

You can view the XAML for the Silverlight control here and the associated code-behind here.

Next Steps

Read Part 2 of this sample for information on initialising the Silverlight control from the ASP.Net host page and an alternative approach to databinding that avoids those "clumsy" converter classes.

Google Blog Logo (googleblog.blogspot.com)