Introducing WCF Syndication Services

Syndication is a mechanism by which applications publish their data in a standardized XML format. By publishing in a standardized feed format, a server application enables remote clients to access your data streams through loosely connected channels, and the data can take on a life of its own in the remote system. Syndicated content is defined by items in a syndicated feed. Remote clients can subscribe to a remote feed and store the data locally, often aggregated with multiple feeds. This enables loosely coupled integration across all sorts of applications and platforms. With syndicated feeds, your data is no longer restricted to your application or even to clients of your application—it can take on a life of its own in aggregation systems and intranet and Internet data repositories. With built-in syndication support in Windows, the Office system, Windows SharePoint Services, and countless client and server applications, syndicated feeds enable users to consume data as they want.

The two most widely used standardized XML specifications for syndicated feeds are RSS and Atom. RSS, or Really Simple Syndication, defines a channel of repeating items. Each item has a title, description, and link, making it an ideal format for sharing news on the Web. Because of the simplicity of RSS, it is the most widely used syndication format today and the standard syndication format used by Windows Live services and the 2007 Microsoft Office System. The schema of RSS is inferred; all elements of the RSS specification are defined without a namespace. Any extensions to the RSS specification are added through elements and attributes defined in custom namespaces.

More Information

More Information

The full RSS specification is available at http://www.rssboard.org/rss-specification. Only a subset of the RSS specification is implemented by the default WCF feed generator; the full RSS specification requires custom extensions.

A simple RSS document is shown in Example 3-10. The XML document exists outside an XML namespace, and any custom elements are defined in explicit namespaces. This feed was generated by using the WCF syndication framework and contains Atom elements using the a10 prefix, defined in the namespace http://www.w3.org/2005/Atom. While the RSS specification defines items such as pubDate to specify the publishing date, the WCF syndication implementation favors Atom standards and includes the Atom equivalent defined in the Atom namespace, which is perfectly legal according to the RSS specification.

Example 3-10. RSS is a (really) simple syndication format that defines a channel of repeating items.

<rss version="2.0" xmlns:a10="http://www.w3.org/2005/Atom">
  <channel>
    <title>Recently Posted: Default</title>
    <description>Recently Posted items for Default</description>
    <item>
      <a10:author>
        <a10:name>Daniel Larson</a10:name>
      </a10:author>
      <title>Test</title>
      <description>Test Wiki Content</description>
      <pubDate>Sun, 24 Feb 2008 23:26:01 -0700</pubDate>
      <a10:updated>2008-02-24T23:32:05-07:00</a10:updated>
    </item>
  </channel>
</rss>

Note

Note

With support for offline synchronization, users can read an RSS feed from my Web site whenever they want, regardless of their Internet connection. Syndicated feeds are also archived and processed in online data stores such as NewsGator Online and Technorati, where the data is saved, tagged, and analyzed by the mass population of the Internet. You can subscribe to my feed at the URL http://feeds.feedburner.com/daniellarson.

The Atom syndication format is similar to RSS but offers richer semantics and is defined in the Atom XML namespace. The Atom format defines a feed element with multiple entry elements, all of which are defined in the XML namespace http://www.w3.org/2005/Atom. Example 3-11 lists the same syndicated document defined in Example 3-10 but instead expresses it in the Atom format.

Example 3-11. The Atom feed expresses a feed of multiple entries.

<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text">Recently Posted: Default</title>
  <subtitle type="text">Recently Posted items for Default</subtitle>
  <id>uuid:256307b6-5e6b-40d8-9a28-74bb1aa25a2a;id=1</id>
  <updated>2008-02-26T01:27:55Z</updated>
  <entry>
    <id>uuid:256307b6-5e6b-40d8-9a28-74bb1aa25a2a;id=2</id>
    <title type="text">Test</title>
    <published>2008-02-24T23:26:01-07:00</published>
    <updated>2008-02-24T23:32:05-07:00</updated>
    <author>
      <name>Daniel Larson</name>
    </author>
    <content type="text">Test Wiki Content</content>
  </entry>
</feed>

By using syndicated feeds as foundational components of your AJAX architecture, you can use the same code for syndication as you use for your application services. Wherever you have lists of repeating items, a feed can be a good architectural fit for the message.

To create your first WCF syndication service, define a service method that returns a SyndicationFeedFormatter object. To make it easy for you, Visual Studio 2008 includes a template for a Syndication Feed Library project type, although you will probably want to include syndication feeds as part of your main WCF service library.

Note

Note

The SyndicationFeedFormatter is an abstract class that serializes a feed into XML using RSS, Atom, or a custom serialization format. You generally return an instance of Atom10FeedFormatter or Rss20FeedFormatter, although WCF provides support for custom syndication formats through custom classes that inherit from SyndicationFeedFormatter.

Within your implementation, create a SyndicationFeed object containing a list of SyndicationItem items. As the last step, return a SyndicationFeedFormatter instance, which will usually be an Rss20FeedFormatter or, preferably, the Atom10FeedFormatter. The SyndicationFeedFormatter takes the feed as an input parameter and serializes it with the formatter. Example 3-12 demonstrates the simplest of feed generators using SyndicationFeed, SyndicationItems, and Atom10FeedFormatter.

Example 3-12. The Hello World syndication feed (KnowledgeBase/FeedDemoService.cs).

using System;
using System.Collections.Generic;
using System.ServiceModel.Syndication;
using System.ServiceModel.Web;
using System.ServiceModel.Activation;
using System.Globalization;
using System.Net;

namespace KnowledgeBase
{
    [AspNetCompatibilityRequirements(RequirementsMode =
            AspNetCompatibilityRequirementsMode.Required)]
    public class FeedDemoService : IFeedDemoService
    {
        public SyndicationFeedFormatter CreateFeed(string title)
        {
            SyndicationFeed feed = new SyndicationFeed(title,
                "A WCF Syndication Feed for " + title, null);
            List<SyndicationItem> items = new List<SyndicationItem>();

            // Create a new Syndication Item.
            SyndicationItem item = new SyndicationItem("An item",
                "Item content", null);
            items.Add(item);
            feed.Items = items;
            return new Atom10FeedFormatter(feed);
        }
    }
}

The WCF syndication programming model is based on the Atom specification. The main syndication objects also map to items in the Atom specification, making Atom the preferred syndication format for WCF services. The syndication object model consists of the following core objects.

  • SyndicationFeed. Defines the top-level feed object, feed in Atom 1.0 or rss in RSS 2.0. The feed contains metadata about the feed and a collection of SyndicationItems.

  • SyndicationItem. Defines the individual feed item, item in RSS 2.0 or entry in Atom 1.0. Items are contained in the channel element in RSS 2.0 or as child elements of feed in Atom 1.0. Items contain collections of categories expressed through the SyndicationCategory class and generally have an author, link, and date published.

  • SyndicationPerson. Represents the content’s author or a contributor. SyndicationPerson defines the properties Email, Name, and Uri and is a common object that is serialized either as the Atom author element or contributor element, depending on which collection it is added to.

  • SyndicationCategory. Represents a tag applied to content and is typically a string applied by the content author to categorize the content. However, the category can also specify a label or schema that can apply special meaning to the tag.

  • SyndicationLink. Specifies a link from a syndicated item and is most often used to link to the resource that the syndicated item represents or to include an associated file such as a podcast or document in an item. SyndicationLink properties include MediaType, which specifies the MIME type of the attachment, RelationshipType, which defines the relationship of the link (alternate, related, self, enclosure, or via), Title, and Uri.

More Information

More Information

For a full reference on System.ServiceModel.Syndication, see the MSDN topic http://msdn2.microsoft.com/en-us/system.servicemodel.syndication.aspx.

To extend the syndication engine with custom elements, you can use the class Syndication-ElementExtension. Examples of common extensions include Microsoft’s Simple List Extensions (SLE 1.0; see http://msdn.microsoft.com/bb190612.aspx) or GeoRSS extensions (see http://www.georss.org), which encode items with geographical data and are typically used to create mashups with mapping services such as Microsoft Virtual Earth.

To create a feed that supports extensions, you can use a loosely typed access model by creating extension objects as needed, or you can create classes that derive from SyndicationFeed and SyndicationItem. The latter is the preferred mechanism and should be considered for any commercial syndication implementation. Although I won’t go into detail on syndication customization, you can read the MSDN topic "Syndication Extensibility" at http://msdn2.microsoft.com/bb924494.aspx for documentation on syndication extensibility.

Syndication feeds are most often used to display recently posted items, especially in an aggregated fashion when results come from various feeds. The sample application’s data access class defines a method GetRecentlyPosted, which returns a list of recently posted syndication items from the specified catalog. Example 3-13 demonstrates the addition of the syndicated feed to the DataService class by returning an item of type SyndicationFeed-Formatter. The SyndicationFeedFormatter object automatically serializes into the response stream when accessed through WebHttpBinding.

Example 3-13. The syndication feed is useful for generating feeds for external consumers (KnowledgeBase/DataService.cs).

using System;
using System.ServiceModel.Web;
using System.ServiceModel;
using System.ServiceModel.Activation;

using KnowledgeBase.Implementation;
using System.Security.Principal;
using System.Web;
using System.ServiceModel.Syndication;
using System.Collections.Generic;

namespace KnowledgeBase
{
    [AspNetCompatibilityRequirements(
            RequirementsMode=AspNetCompatibilityRequirementsMode.Required)]
    public class DataService : IDataService, IKnowledgeBaseFeedServer
    {
        // previous code omitted...

        public SyndicationFeedFormatter CreateRecentlyPostedFeed(string catalog)
        {
            SyndicationFeed feed =
                new SyndicationFeed("Recently Posted: " + catalog,
                "Recently Posted items for " + catalog, null);

            DataRetrieval knowledgeBase =
                new DataRetrieval(HttpContext.Current.User);
            List<SyndicationItem> items = knowledgeBase.GetRecentlyPosted(catalog);
            feed.Items = items;

            HttpContext.Current.Response.Cache.SetExpires(
                DateTime.Now.AddYears(-1));
            WebOperationContext.Current.OutgoingResponse.LastModified =
                DateTime.UtcNow;

            SyndicationFeedFormatter formatter = new Atom10FeedFormatter(feed);
            return formatter;
        }
    }
}

By implementing an additional interface for the feed generator, you can support a friendly REST interface for the catalog’s recently posted feed. Example 3-14 defines the interface for the feed server that can be added to DataService. Notice that I’m using the UriTemplate class to pass in the catalog and title parameters and the ServiceKnownType attribute to specify the well-known return type. ServiceKnownType is required by the WCF runtime and is used to maintain compatibility with SOAP-based service clients, although WCF will serialize the feed into XML through the WebHttp behavior.

Example 3-14. The knowledge base recently posted interface uses the UriTemplate and SyndicationFeed implementations (KnowledgeBase/IKnowledgeBaseFeedServer.cs).

using System;
using System.ServiceModel.Syndication;
using System.ServiceModel;
using System.ServiceModel.Web;

namespace KnowledgeBase
{
    [ServiceKnownType(typeof(Atom10FeedFormatter))]
    [ServiceContract]
    interface IKnowledgeBaseFeedServer
    {
        [OperationContract]
        [WebGet(UriTemplate = "{format}/{catalog}",
                BodyStyle = WebMessageBodyStyle.Bare)]
        SyndicationFeedFormatter CreateRecentlyPostedFeed(
            string format, string catalog);
    }
}

In the previous code samples, I demonstrated only the feed generation capabilities of the WCF syndication framework. The syndication framework also includes support for parsing syndicated feeds and support for parsing RSS 2.0 and Atom 1.0 into the common syndication object model.

I also described the Atom syndication format because it is the basis of the syndication engine. The Atom protocol contains more than just the syndication specification, however. It is also a rich protocol for publishing content using the REST programming model, which makes it an ideal protocol for collaborative data input in AJAX applications.

More Information

More Information

For more information on the Atom publishing protocol, see http://atomenabled.org.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset