Introduction
This article shows how to create a simple RSS Reader in Silverlight. This is a beginner article showing basic Templating, Binding and such basic concepts in Silverlight.
Background
The source code consists of a Silverlight project, a Web Project and a WCF service hosted in the web application. I developed this sample in Visual Studio 2008.
Using the Code
We can start creating a Silverlight application from the Visual Studio templates and it'll automatically create a Silverlight project and a Web application into which Silverlight is hosted. We need to fetch data from the feed URL that a user entered and for that purpose, we are going to use a WCF service so that the Silverlight client can make asynchronous calls and can fetch the response. So let's start by adding a WCF service to the Web application, here in my sample its RSSReaderService.svc. If we add WCF service directly to the Web application instead of creating a new service project, then the service will be hosted in the web application itself when we start the application. I created a ServiceContract IRSSReaderService
and added an OperationContract
GetFeed(string uri)
, a method which defines an operation for the service contract.
namespace RSSReader.Web
{
[ServiceContract]
public interface IRSSReaderService
{
[OperationContract]
IEnumerable<RSSItem> GetFeed(string uri);
}
}
We need to implement the operation contract GetFeed(string uri)
in our service code behind which is implementing IRSSReaderService
. We are using
System.ServiceModel.Syndication
, a namespace using for Syndication object model, for loading the syndication feed from the XmlReader
instantiated with the specified feed URL. For sending the properties from the feed to the client, we created a DataContract RSSItem
with DataMember
s like Title, Summary, PublishDate and Permalink. We can customize the data members according to our requirement, but here I am simply using this much information to send to the client.
[DataContract]
public class RSSItem
{
[DataMember]
public string Title { get; set; }
After creating this DataContract
, we create an XmlReader
with the specified URL and load the SyndicationFeed
items from this XMLReader
. Now we can use LINQ for iterating through this syndication items and for fetching the required information from those items. We are populating the RSSItem
that we created and sending an IEnumerable
of this object from the service to the client. So our GetFeed(string url)
method implementation looks like:
[AspNetCompatibilityRequirements(RequirementsMode =
AspNetCompatibilityRequirementsMode.Allowed)]
public class RSSReaderService : IRSSReaderService
{
public IEnumerable<RSSItem> GetFeed(string uri)
{
XmlReader reader = XmlReader.Create(uri);
SyndicationFeed rssFeed = SyndicationFeed.Load(reader);
var items = from p in rssFeed.Items
select new RSSItem
{
Title = p.Title.Text,
Summary = p.Summary.Text.Trim(),
Permalink = (p.Links.FirstOrDefault() != null) ?
p.Links.FirstOrDefault().GetAbsoluteUri() : null,
PublishDate = p.PublishDate.LocalDateTime.ToString("dd/MMM/yyyy")
};
return items;
}
}
So our service is completed and ready for consumption by the client. Now we need to create the Silverlight client. Add service reference to the Silverlight project and then create a user control
in the Silverlight project, in the sample you can see the user control UC_RSSReader.xaml. I added some controls like ListBox
in this usercontrol, templated and added binding for those controls.We edited the ItemTemplate for the ListBox
and added custom data template which consists of TextBlock
s and ListBox
to display the feed data as required. We can customize this as per our requirement or as per the amount of data to be displayed. Now we are having the usercontrol
that is binded to the corresponding properties. ListBox
is displaying the feed data from the URL and the XAML looks like:
<ListBox x:Name="RSSFeed"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Grid.Row="2"
Grid.ColumnSpan="2">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid MinWidth="{Binding ElementName=LayoutRoot, Path=ActualWidth}"
MaxWidth="{Binding ElementName=LayoutRoot, Path=ActualWidth}">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Title}"
FontFamily="Verdana"
FontSize="13" />
<TextBlock Grid.Row="2"
Text="{Binding PublishDate}"
HorizontalAlignment="Left"
FontFamily="Verdana"
FontSize="11" />
<HyperlinkButton Grid.Row="2"
Content="Read Article>>"
NavigateUri="{Binding Permalink}"
HorizontalAlignment="Center"
FontFamily="Verdana"
FontSize="11"
FontStyle="Italic"
ToolTipService.ToolTip="{Binding Title}"
TargetName="__blank" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
We are not using MVVM pattern for this application as this is a very basic sample. We can follow the normal way of event subscription and all, i.e., straight forward and we have all the logic in the code behind itself. While clicking the fetch Button
, we are sending the request to the service with the feed URL entered, fetching the data from the service and binding that result with ListBox
. ListBox
will display the Title, PublishDate and also a permalink to the original feed item.
private void FetchRSS_Click(object sender, RoutedEventArgs e)
{
if (!string.IsNullOrEmpty(RSSFeedUrlTextBox.Text.Trim())
&& Uri.IsWellFormedUriString(RSSFeedUrlTextBox.Text.Trim(),
UriKind.Absolute))
{
LoadingTextBlock.Visibility = Visibility.Visible;
RSSFeed.Items.Clear();
RSSReaderServiceClient RSSReaderServiceClient = new RSSReaderServiceClient();
RSSReaderServiceClient.GetFeedCompleted +=
new EventHandler<GetFeedCompletedEventArgs>
(RSSReaderServiceClient_GetFeedCompleted);
RSSReaderServiceClient.GetFeedAsync
((new Uri(RSSFeedUrlTextBox.Text)).ToString());
}
}
void RSSReaderServiceClient_GetFeedCompleted
(object sender, GetFeedCompletedEventArgs e)
{
RSSFeed.ItemsSource = e.Result;
Add this usercontrol
to the main page and compile it. Before running the application, don't forget to put the cross domain policy file in the web application root. Otherwise, the Silverlight client can't communicate with the WCF service. If you get any run time errors for the sample application, then delete and add the service reference again in the Silverlight project.
History