V minulém článku jsme si ukázali jak pomocí třídy WebClient stáhnout obsah souboru. Dnes si ukážeme možnost, jak v naší aplikaci zobrazit RSS kanál.
Design aplikace
Design aplikace je velice jednoduchý. Naše uživatelské rozhraní obsahuje pouze tlačítko, které po stisku zobrazí obsah jednoho RSS kanálu.
Pro testovací účely jsem si v mojí webové aplikaci vytvořil adresář Files, do kterého jsem umístil soubor posts.rss
Obsah RSS kanálu se zobrazuje pomocí ItemsControl, kde jsem si vytvořil vlastní šablonu aby výsledek vypadal aspoň trošku k světu:
<UserControl x:Class="WebClientViewRssSample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Content="Zobrazit RSS" Click="ViewRssButtonOnClick" Margin="5"/>
<TextBox Grid.Column="1" Grid.ColumnSpan="2" IsReadOnly="True" Text="../Files/posts.rss"
HorizontalAlignment="Left" VerticalAlignment="Center"/>
<ScrollViewer
Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto">
<ItemsControl x:Name="ui_Data">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="1" Margin="5">
<StackPanel>
<TextBlock Text="{Binding Title}" FontWeight="Bold"/>
<TextBlock Text="{Binding Description}" TextWrapping="Wrap"/>
</StackPanel>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</UserControl>
Jednoduše se pro každou položku RSS zobrazí rámeček s titulem (tučně) a jeho popisem.
Pro objektovou reprezentaci jednotlivých položek jsem si vytvořil třídu Post
public class Post
{
public string Title { get; set; }
public string Description { get; set; }
public DateTime PubDate { get; set; }
internal static Post FromFeedItem(SyndicationItem feedItem)
{
string description = string.Empty;
if ( feedItem.Summary != null )
description = feedItem.Summary.Text;
else
description = (( TextSyndicationContent ) feedItem.Content).Text;
return new Post()
{
Title = feedItem.Title.Text,
PubDate = feedItem.PublishDate.DateTime,
Description = description
};
}
}
Třída obsahuje vlastnosti reprezentující Titul, popis a datum publikování. Kromě těchto základních vlastností obsahuje metodu FromFeedItem, která příjme objekt typu SyndicationItem (reprezentuje položku RSS kanálu), přečte potřebné hodnoty a vrátí mi můj objekt Post:
Odkud, ale dostanu SyndicationItem objekt? Ve jmenném prostoru System.ServiceModel.Syndication (knihovna System.ServiceModel.dll) se nachází třída SyndicationFeed, která reprezentuje náš RSS (Atom) kanál. Tato třída nabízí statickou metodu Load, která přebírá jako parametr objekt typu XmlReader, který má rovněž metodu Load a jedno její přetížení přebírá parametr typu Stream, který dostaneme po výsledku asynchronního volání pomocí třídy WebClient.
Zavolám tedy metodu pro asynchroní stažení:
_webClient.OpenReadAsync(new Uri("../Files/posts.rss", UriKind.Relative));
Z výsledku si získám Stream a vytvořím XmlReader,
XmlReader reader = XmlReader.Create(args.Result);
který potom předám jako parametr metodě Load třídy SyndicationFeed
SyndicationFeed feed = SyndicationFeed.Load(reader);
Pak jednoduše pomocí LINQu si projdu všechny položky a zobrazím v UI
var query = from feedItem in feed.Items
select Post.FromFeedItem(feedItem);
ui_Data.ItemsSource = query;
Výsledek si můžete prohlédnout na testovací stránce: http://lukaskubis.net/Demos/Apps/WebClientViewRssSampleTestPage.html
Poznámka: Na testovací stránce používám jako zdroj dat posts.txt (nikoliv rss). Je to z důvodu, že rss není defaultně na IISku povolené a já si to momentálně sám poolit nemůžu, proto ta změna přípony.
Materiály ke stažení
Demo je ke stažení zde