Condensing meaning from the vapor of nuance.

Has Microsoft Killed RSS?

clock April 2, 2008 16:18 by author brian.kuhn

 

With the release of Microsoft .NET 3.5 the .NET framework finally comes with native support for web content syndication, and provides the ability to parse and generate Atom 1.0 and RSS 2.0 syndicated content. This new feature set is contained by the System.ServiceModel.Web assembly and is organized under the System.ServiceModel.Syndication namespace. The System.ServiceModel.Syndication namespace contains all of the classes that make up the Syndication Object Model. The object model that Microsoft provides represents a format agnostic methodology, where syndicated content is described using the entity model and then is formatted to conform to a specific syndication content format such as Atom or RSS. This type of model has the advantage of providing a layer of abstraction between the content to be syndicated and the format used to publish the content, but may eventually lead to the death of RSS as a popular syndication format.

 

Instantiate, format, rinse and repeat

The first point to understand is that the abstraction layer provided by the syndication object model maps almost 1:1 with the Atom 1.0 syndication format. The properties exposed by the object model's SyndicationFeed and SyndicationItem classes represent a sub-set of the Atom feed and Atom entry elements. From the perspective of designing a format agnostic object model, this was a good design choice as the Atom 1.0 specification can easily describe the RSS 2.0 data set. The tables below outline the basic API you program against when defining a syndication feed and its associated items:

SyndicationFeed Class Properties  
Name Description
Authors Gets a collection of authors of the feed.
BaseUri Gets and sets the base URI for the SyndicationFeed instance.
Categories Gets a collection of categories for the feed.
Contributors Gets a collection of the contributors to the feed.
Copyright Gets and sets copyright information for the feed.
Description Gets and sets a description of the feed.
Generator Gets and sets the generator of the feed.
Id Gets and sets the unique identifier of the feed.
ImageUrl Gets and sets the image URL for the feed.
Items Gets a collection of the feed items contained in the feed.
Language Gets and sets the language of the feed.
LastUpdatedTime Gets and sets the time the feed was last updated.
Links Gets the links associated with the feed.
Title Gets and sets the title of the feed.

 

SyndicationItem Class Properties  
Name Description
Authors Gets a collection of authors of the item.
BaseUri Gets and sets the base URI for the SyndicationItem instance.
Categories Gets a collection of categories for the item.
Content Gets and sets the content of the item.
Contributors Gets a collection of the contributors to the item.
Copyright Gets and sets copyright information for the item.
Id Gets and sets the unique identifier of the item.
LastUpdatedTime Gets and sets the time the item was last updated.
Links Gets the links associated with the item.
PublishDate Gets and sets the publish date for the item.
Summary Gets and sets the summary of the item.
Title Gets and sets the title of the item.

This format agnostic content model is at face value a nice abstraction, as it allows you to define the content you wish to syndicate without prior knowledge of the content format it will be syndicated in. You can define your content once and then generate both an Atom 1.0 syndication feed and an RSS 2.0 syndication feed from the same content data representation. You can in effect kill multiple content formats with one stone.

 

The devil is in the (formatter) details

There is however, a big catch to this type of model, and it is implied by the remarks that can be found for the SyndicationFeed and SyndicationItem classes. If you use the Atom 1.0 formatter to generate an Atom feed, the resulting output does not utilize any namespace prefixed syndication extensions, as the object model as mentioned previously maps directly to the Atom 1.0 content format. However, if you use the RSS 2.0 formatter to generate an RSS 2.0 feed, the resulting output can potentially contain elements that use the a10 XML prefix, and are mapped to the Atom syndication XML namespace. The documentation indicates which properties/collections will result in this situation, and so while you have gained a degree of isolation from the content format you will be syndicating your content in; in the case of RSS 2.0 you will need to have prior knowledge of how the SyndicationFeedFormatter you are using handles entities in the model that fall outside the RSS format.

If you are generating and consuming syndicated content using the Microsoft .NET 3.5 service model syndication architecture, these issues are not much of a problem, but can become potentially problematic when other types of clients attempt to consume your RSS feeds. This is a situation where you can be completely per specification, but still end up with an indigestible feed. Syndication formats like Atom and RSS were built to be extensible, but the level of adoption of an extension is a limiting factor, as the more widely adopted extensions are the most likely to be natively supported by the client software that will be consuming your feeds.

While getting actual metrics on syndication extension usage can be difficult, but some common statistics can be seen at Blogspot and Syndic8. These rough statistics seem to indicate:

  • The extension of RSS feeds using the Atom element set is not widely adopted.
  • One of the most commonly adopted syndication extensions is the Dublin Core Element Set. (More on this later)

When implementing the Rss20FeedFormatter class, Microsoft made the decision to represent the syndication model entities that fell outside the RSS 2.0 specification by extending the resulting RSS feed using Atom 1.0 elements. I would argue that this was the biggest mistake made in the implementation of the .NET syndication service model. If you are faced with needing to extend a syndication format, you should consider using extensions that are well documented and widely adopted. I question whether extending an RSS feed using Atom elements was the best decision in this context, as it appears that it is not a widely adopted method of extending RSS feeds.The decision to use Atom 1.0 elements may have been driven by the fact that all of the extension metadata can be consumed natively by the .NET syndication service model, as the Atom syndication format is already implemented in the .NET framework. If the .NET syndication service model is lacking anything, it is native support/implementations of widely adopted syndication extensions. It is easy enough to use the SyndicationElementExtension class and AttributeExtensions/ElementExtensions properties to provide custom syndication extension information, but you the developer are left to do the work. What is worse is that for the most common syndication extensions, we will all be reinventing the same wheel.

 

Ireland, more than just the third largest island in Europe

If we assume that there may be some issues with Atom extended RSS feeds, all is not lost. The Dublin Core Metadata Element Set (and its successor, the Dublin Core Metadata Terms) provide a well documented and more importantly widely adopted option for representing the syndication service model information that falls outside what can be represented using the RSS syndication format. The tables below outline how the .NET syndication service model entities map when using the standard Rss20FeedFormatter class to generate an RSS feed, and how you could possibly map them using the Dublin Core Metadata Initiative (DCMI) extensions:

SyndicationFeed Class      
Property Rss20FeedFormatter DCMI Element Set Extension DCMI Terms Extension
Authors <a10:author> <dc:creator> <dcterms:creator>
Contributors <a10:contributor> <dc:contributor> <dcterms:contributor>
Id <a10:id> <dc:identifier> <dcterms:identifier>
Links <a10:link> <dc:relation> <dcterms:relation>

 

SyndicationItem Class      
Property Rss20FeedFormatter DCMI Element Set Extension DCMI Terms Extension
Authors <a10:author> <dc:creator> <dcterms:creator>
Content <a10:content> <dc:description> <dcterms:description>
Contributors <a10:contributor> <dc:contributor> <dcterms:contributor>
LastUpdatedTime <a10:updated> <dc:date> <dcterms:modified>
Links <a10:link> <dc:relation> <dcterms:relation>

It should be noted that the DCMI recommendations indicate that that encoding schemes should be implemented using the xsi:type attribute of the XML element for the property. The name of the encoding scheme should be given as the attribute value, and should be in the form of an XML qualified name (QName) which associates the scheme name with the appropriate namespace name. This recommendation is relevant since you can indicate the encoding of the DCMI identifier element, for example: <dc:identifier xsi:type="dcterms:URI">http://www.example.org/thing</dc:identifier>. We will also want to follow the .NET framework's convention for the Authors collection, which uses the RSS managingEditor element for feeds and the RSS author element for items when only one author is present in the Authors collection.

 

Build a better feed formatter and ...

So now that we have defined how we can represent the syndication model entities using DCMI syndication extension elements, it is time to put our code where our mouth is and create a custom feed formatter. You can create your own custom feed formatter by inheriting from the SyndicationFeedFormatter abstract base class. I have included in this post a proof of concept custom syndication feed formatter that uses the DCMI Element Set to serialize and deserialize a syndication feed and its associated items using the mappings defined in the above table. It isn't production quality code by any means, but it demonstrates how you can create a custom feed formatter that utilizes a syndication extension with almost 30% adoption, as opposed to the relatively rare (at least for now) Atom format elements. The use of the dc:description element is not a great way for representing encoded content, but there are a variety of commonly used syndication extensions that you could use. The basic idea to take away is you should consider creating creating a custom syndication feed formatter that utilizes the more widely adopted syndication extensions if you plan on using the .NET syndication service model to generate RSS feeds.

 

Conclusion

The greater amount of work required to generate a 'clean' RSS feed compared to that of generating an equivalent Atom feed, combined with the use of a less common syndication extension leads me to believe that there may soon be a shift away from RSS as a syndication format, at least within the sub-community of .NET that chooses to use the new syndication service model. Why deal with the possible headaches when you can just as easily provide Atom feeds? Perhaps the time has come for RSS to slowly fade away. The Atom syndication format is  arguably a better format for syndicating content, has an actual registered MIME content type, and is an Internet standards track protocol for the Internet community. There may be a slightly higher learning curve for publishing content in Atom, but with the variety of tools and frameworks available to .NET developers, there are few reasons to not move to Atom.

That said, the introduction of Atom as the primary means of extending RSS in .NET 3.5, coupled with the RSS Profile recommendation of including an atom:link element in RSS feeds will inevitably lead to a wider adoption of Atom as a syndication extension. If web browsers and tools/frameworks grow to support Atom as an RSS syndication extension, RSS may continue to be with us for awhile; if not, the days of RSS are likely numbered.

Proof of Concept Project: DublinCoreFeedFormatter.zip (69.73 kb)


Argotic Syndication Framework 2007.1 Released

clock October 3, 2007 15:03 by author brian.kuhn
The 2007.1 version of the Argotic Syndication Framework has been released. This release offers a number of new features, including asynchronous retrieval of syndication resources, support for legacy syndication formats, simplified detection and inclusion of syndication extensions, a format agnostic means of retrieving syndication feed information, and an overall improvement to the framework namespace organization and performance.

SQL user-defined functions (UDF) for consuming and generating RFC-822 DateTime's

clock July 5, 2007 15:31 by author brian.kuhn
SQL server user-defined functions (UDF) for converting to and from the RFC 822 DateTime format.

Leveraging Active Directory As A Membership and Role Management Data Store in ASP.NET 2.0

clock November 7, 2006 21:29 by author brian.kuhn
In this post I show how you can use the ActiveDirectoryMembershipProvider and AuthorizationStoreRoleProvider classes to manage your application's authentication and authorization requirements with forms based authentication.

ApplicationSettingParameter: Binding data source controls to application settings variables

clock October 23, 2006 15:29 by author brian.kuhn
While there was no out-of-box ASP.NET parameter for handling data stored in the application settings configuration collection, in this post I show how you can easily write your own.

Calendar

<<  July 2008  >>
MoTuWeThFrSaSu
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910