Программирование HTTP с использованием WCF - Создание SyndicationFeed
ОГЛАВЛЕНИЕ
Создание SyndicationFeed
Существует два способа создания объекта SyndicationFeed. Можно создать один экземпляр и заполнить его члены вручную, либо заполнить весь SyndicationFeed из существующего канала. Оба способа просты в исполнении и скрывают от разработчика особенности реализации конкретного формата подключения. В следующем коде показан способ создания вручную объекта SyndicationFeed.
SyndicationFeed feed = new SyndicationFeed();
feed.Title.Text = "The Cybertopian Chronicle";
Заголовок является всего лишь одним из многих свойств, которые можно устанавливать, поэтому дополнительные возможности следует искать в документации.
Зачастую возникает необходимость считать информацию из существующего канала и выполнить какие-то операции на основе содержимого этого канала. В новом интерфейсе API объединения предусмотрено создание SyndicationFeed и автоматическое заполнение его состояния из существующего канала. Все, что требуется для запуска, это URI-адрес существующего канала или XmlReader, предназначенный для его чтения. В следующем коде показан способ подключения к существующему каналу в Интернете и извлечение из него некоторой информации:
Uri feedUri = new Uri("http://blogs.msdn.com/justinjsmith/atom.xml");
SyndicationFeed feed = SyndicationFeed.Load(feedUri);
Console.WriteLine(feed.Title.Text);
// outputs "The Cybertopian Chronicle"
В тип SyndicationItem входит более 35 членов. Многие из них являются свойствами, связанными с установкой или извлечением полей, таких как идентификатор элемента, дата последнего обновления, заголовок или фактическое содержимое. Существуют многочисленные члены, облегчающие расширение содержимого, хранящегося в SyndicationItem. Имеется много расширений RSS и ATOM (Microsoft Simple List Extensions, Yahoo Media RSS и GeoRSS, помимо многих других), и как SyndicationFeed, так и SyndicationItem допускает расширение с целью включения любого существующего расширения RSS или ATOM.
В каналах может быть много элементов, и одновременная их загрузка является негодным вариантом в случае больших каналов. SyndicationFeed справляется с этой ситуацией, предоставляя объект SyndicationItem в качестве IEnumerable<SyndicationItem>. Эта реализация облегчает работу с большим числом объектов SyndicationItem, поскольку в ней используется преимущество применения итератора среды .NET Framework 2.0. Итерации на наборе объектов SyndicationItem можно также выполнять с помощью LINQ. Это может значительно сократить объем кода, требуемого для извлечения данных из канала.
Объединенный интерфейс API определяет несколько типов, преобразующих SyndicationFeed в форматы RSS 2.0 и ATOM 1.0. Фактически, можно создать один SyndicationFeed, заполнить его объектами SyndicationItem, затем предоставить этот канал одновременно как RSS и ATOM. На рис. 5 показано, как получить канал ATOM 1.0, преобразовать его в RSS 2.0 и вывести новое представление RSS на консоль.
Рис. 5 Transforming a Feed
// read an ATOM feed
Uri feedUri = new Uri("http://blogs.msdn.com/justinjsmith/atom.xml");
SyndicationFeed feed = SyndicationFeed.Load(feedUri);
// transform it to RSS
Rss20FeedFormatter formatter = new Rss20FeedFormatter(feed);
XmlWriter writer = XmlWriter.Create(Console.Out, null);
// write it to the Console
formatter.WriteTo(writer);
writer.Flush();
Сочетая объединенный интерфейс API с моделью программирования HTTP в среде WCF, можно предоставить канал от настроенного URI-адреса и вернуть RSS или ATOM, основанные на компоновке этого URI-адреса. На рис. 6 показано, как определить операцию в контракте службы, которая параметр строки запроса от принятого HTTP GET использует для возврата либо канала RSS, либо канала ATOM. Обратите внимание на использование SyndicationFeedFormatter<SyndicationFeed> в контракте операции. Как Rss20FeedFormatter, так и Atom10FeedFormatter являются производными от SyndicationFeedFormatter<TSyndicationFeed>.
Рис. 6 Exposing a Feed from a Customized URI
[ServiceKnownType(typeof(Atom10FeedFormatter))]
[ServiceKnownType(typeof(Rss20FeedFormatter))]
[ServiceContract]
interface IPictureService {
[OperationContract]
[WebGet(UriTemplate="Pictures?format={format}")]
SyndicationFeedFormatter<SyndicationFeed> Feed(String format);
}
class PictureService : IPictureService {
public SyndicationFeedFormatter<SyndicationFeed> Feed(String format){
// create the syndication feed
SyndicationFeed feed = new SyndicationFeed();
// add the items to the feed (omitted)
// check the argument & return the right format
if(format.ToLower() == "rss"){
return new Rss20FeedFormatter(feed);
}
return new Atom10FeedFormatter(feed);
}
}