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.