asp:feature
LANGUAGES: C#
ASP.NET VERSIONS: 1.0 | 1.1 | 2.0
Syndicate Your Site
Dynamically Create RSS Syndication Feeds
By Scott Mitchell
If you visit many weblogs, such as those at http://blogs.msdn.com or http://weblogs.asp.net, you may have noticed that many blogs contain a little orange button with the text XML or RSS (see Figure 1). Clicking on that button takes you to a page that dumps out a bunch of XML content. This XML content, called an RSS syndication feed, contains information about the blog's latest posts, such as the title of a post, when it was made, a link to the complete post, and a synopsis of the post. RSS is a standard that specifies an XML format for syndicating metadata about Web site content in a machine-readable format.
Figure 1: Sites that provide an RSS feed typically use a little orange
button that links to the site's RSS feed.
Syndicating content through RSS isn't limited to blogs; a bevy of Web sites syndicate information about their content using RSS, including CNet's News.com, Yahoo! News, eWeek.com, and Microsoft's MSDN site. You may be wondering why any Web site would want to syndicate metadata about its content. There are two main reasons:
One. Other Web sites can read the syndicated information, and display this on their own Web site. This gives the syndicated content more exposure since it can be easily delivered to multiple Web sites.
For example, at the official ASP.NET Web site (http://www.asp.net), there's an RSS feed listing the latest ASP.NET-related articles on the Web. On the Web site I run, 4GuysFromRolla.com, I list these recent articles on the homepage (http://aspnet.4GuysFromRolla.com), so a visitor to my site can see the titles and descriptions of the latest ASP.NET articles gathered by http://www.asp.net. Clicking on one of these titles will take the user to the particular article.
Two. Many people are starting to use RSS aggregators as a means for keeping up-to-date with online information. An RSS aggregator is a desktop or Web application that periodically checks the RSS feeds from a specified list of sites. If there are any new content items, the RSS aggregator alerts the user so that they can view information about the new content through their aggregator program, without having to fire up a browser and visit the site. Web sites that want to attract those who are using RSS aggregators need to provide information about their latest content using RSS.
In Displaying Syndicated Content, which examined how to consume an RSS feed and display it in an ASP.NET Web page. In this article, we'll look at how to syndicate content using RSS. The lessons learned and code presented in this article will be especially beneficial to those who maintain a Web site that provides regularly updated content and who are interested in extending their content's reach through syndication.
The History of RSS
By 1999, Netscape was creating its my.netscape.com Web site, which, like My Yahoo! and other personalized portal sites, allowed users to customize the information displayed on the personalized portal's home page. Netscape needed a standardized way to consume and display different content on a user's personalized homepage. To surmount this problem, they introduced a standardized way by which a Web site could syndicate information about its content. This standard was called RDF Site Summary (RSS) 0.9, as it required conformance to a previous W3C standard called RDF. (RDF is a standard for providing information in a machine-readable, XML format. See http://www.w3.org/RDF/ for more information.) Eventually RSS 0.9 became RSS 1.0.
As the RSS 1.0 specification was being formed, Netscape introduced RSS 0.91, which dropped the adherence to the RDF specification. Dave Winer then independently extended RSS 0.91 to RSS 0.92, adding functionality to the RSS spec. The latest work on RSS done by Dave Winer is RSS 2.0. With this latest version, Dave has changed the meaning of the RSS acronym from RDF Site Summary to Really Simple Syndication.
The important thing to understand is that there is a bit of a difference between the various RSS versions, most noticeably between RSS 1.0 (which maintains adherence to the RDF standard), and RSS 0.91, RSS 0.92, and RSS 2.0 (which does not). When deciding to syndicate your Web site's content, you'll need to choose which standard to use to syndicate your site's content. There's really no wrong choice; virtually all RSS aggregator applications can consume both valid feeds from any RSS version. However, I would encourage you to use the latest version, RSS 2.0, as it is the standard version we'll be syndicating for in this article. Therefore, from this point forward, when I use the term RSS I am referring to RSS 2.0.
Know the RSS 2.0 Specification
RSS is designed to syndicate information about Web site content. For example, the Web site I maintain, 4GuysFromRolla.com, offers an RSS feed (http://aspnet.4GuysFromRolla.com/rss/rss.aspx) that provides the following information about the 10 most recent articles:
- The title of the article.
- The URL of the article.
- The date and time the article was published.
- A short synopsis of the article.
The RSS specification provides pre-defined XML elements to express this and other information about a Web site's content items. Additionally, RSS provides XML elements to furnish information about the syndication channel. In RSS, a channel provides specific syndicated content. Each RSS feed contains a single channel. A Web site can contain an arbitrary number of RSS feeds, and can therefore contain an arbitrary number of channels. A Web site might opt to use multiple RSS feeds, having each feed focus on a specific type of content. Yahoo! News, for example, provides 16 separate RSS feeds at http://news.yahoo.com/rss - one for top stories, one for U.S. news, one for world news, one for business news, and so on. RSS channels are akin to television channels in that each TV channel provides a specific type of content, e.g. MTV provides music videos while CNN provides news.
The basic form of an RSS 2.0 document contains an
http://www.4GuysFromRolla.com/
4GuysFromRolla.com
Corporation All Rights Reserved.
http://4guysfromrolla.com/020404-1.aspx
This article looks at using HTTP handlers to
prevent HTTP access to certain types of files.
http://4guysfromrolla.com/012804-1.aspx
This article examines skmMenu, an open-source
custom ASP.NET menu control.
http://4guysfromrolla.com/010704-1.aspx
This article, by Jisun Lee, examines how to create
and consume .NET Web services.
Figure 2: An RSS 2.0 syndication feed contains an
As Figure 2 illustrates, the RSS feed contains a single
Element |
Description |
|
Provides the title of the channel. |
|
Provides a URL to the channel. |
|
Provides a brief description of the channel. |
|
Language in which the channel is written. Must be one of the language values defined by the W3C (see RFC #1766). |
|
Copyright notice. |
|
E-mail address of the person responsible for editorial content. |
|
E-mail address of the person responsible for the technical issues of the channel. |
|
Time to live. Indicates how long, in minutes, an RSS aggregator should wait before rechecking the feed to see if there is new content. |
|
URL to an image file for the channel. |
Figure 3: Selected RSS 2.0 specification elements.
After the elements that describe the
Element |
Description |
|
Title of the content item. |
|
URL of the content item. |
|
Synopsis of the content item. |
|
E-mail address of the content item's author. |
|
String value indicating to which category the content item belongs. |
|
URL to a Web page that has user comments or an online discussion about the content item. |
|
Describes a media object that is attached to the content
item. For example, if there is a movie associated with the content item, the
|
|
Globally unique identifier for the content item. |
|
Date/time the content item was published. This date/time must conform to the date/time format specified in RFC #822. |
|
RSS channel from which that the item came. |
Figure 4: RSS 2.0 specification
Syndicate Your Content with RSS
There are two approaches for syndicating content with RSS: create a static RSS feed XML file on the Web server, or have the RSS feed be an ASP.NET Web page that, when requested, dynamically generates the appropriate XML.
The benefit of using a static XML file is performance. No matter how you look at it, serving a static page from a Web server will never be less efficient that generating the same response using a dynamic, server-side technology, like ASP.NET. The downside of using a static file is that this file has to be updated in some manner. Typically updating a static file can be done in one of two ways:
- Periodic Polling. A program is written that periodically checks the database for new content and updates the RSS feed if needed. This program would need to be installed on the Web server and configured to run at certain intervals.
- On-Demand Updates. If you use a content management system (CMS) - either a commercial product or a home-grown one - that you can tap into, you could have the RSS feed's XML file updated only when it needs to be, i.e. when new content is added.
Using a static XML file as an RSS feed typically requires a certain level of access to the Web server or the content creation process. That is, you'll need to be able to schedule a program to run periodically that will update the XML file, or you'll need to be able to integrate such a program into the content management system. If you don't have this level of access, or don't want to write a program that can update the RSS feed's XML file, you can create an ASP.NET Web page that will dynamically generate the RSS feed's XML content. The chief concern of using a dynamic server-side technology like ASP.NET - performance - can be allayed by employing caching.
The .NET Framework contains a bevy of classes designed to work with XML data. These classes, in the System.Xml namespace, include classes to create XML documents, modify XML documents, read XML documents, and parse through XML documents. To syndicate Web site content, we simply need to create an XML document - the preferred (and most efficient) means of generating XML in .NET is to use the XmlTextWriter class. (For a discussion on the best practices for working with XML in .NET, be sure to read Aaron Skonnard's article ".NET XML Best Practices" at http://support.softartisans.com/kbview.aspx?ID=673.)
The XmlTextWriter class provides methods to write XML elements, attributes, and text values to some backing store. For example, the XmlTextWriter can write XML content to a file or to any general Stream. It can also write to a TextWriter. The Stream or TextWriter the XmlTextWriter should write to is passed into the XmlTextWriter's constructor.
Figure 5 shows the complete source code for an ASP.NET Web page that syndicates content to an RSS 2.0 syndication feed. To implement the code, create a new ASP.NET Web page. In the HTML portion, clear out all HTML markup, leaving just the @Page directive. In the code-behind class, add the code in Figure 5 to the Page_Load event handler. (The complete code in a Visual Studio.NET project is available for download; see end of article for details.)
// Set the content-type.
Response.ContentType = "text/xml";
Response.ContentEncoding = Encoding.UTF8;
// Check to see if a cached version exists.
if (Cache["RssFeed"] == null)
{
// Build up the cache dynamically.
DataTable articleData = CreateDataSource();
// Use an XmlTextWriter to write XML data to a string.
StringWriter sw = new StringWriter();
XmlTextWriter writer = new XmlTextWriter(sw);
// Write out
writer.WriteStartElement("rss");
writer.WriteAttributeString("version", "2.0");
// Write out
writer.WriteStartElement("channel");
// Write out
writer.WriteElementString(
"title", "Example RSS Feed Title");
writer.WriteElementString(
"link", "http://myWebSite.com/");
writer.WriteElementString("description",
"This is a demonstration of creating an RSS feed.");
writer.WriteElementString("ttl", "60");
// Write out an
const int RSS_ITEMS = 10;
for (int i = 0; i < RSS_ITEMS; i++)
{
// Write out
writer.WriteStartElement("item");
// Write out
writer.WriteElementString("title",
articleData.Rows[i]["title"].ToString());
writer.WriteElementString("link", String.Format(
"http://myWebSite.com/article.aspx?id={0}",
articleData.Rows[i]["articleID"]));
writer.WriteElementString("description",
articleData.Rows[i]["synopsis"].ToString());
writer.WriteElementString("author",
articleData.Rows[i]["author"].ToString());
// Use DateTimeFormatInfo "r" to use RFC #1123 date
// formatting (same as RFC #822).
writer.WriteElementString("pubDate", ((DateTime)
articleData.Rows[i]["dateAdded"]).ToString("r"));
// Write out .
writer.WriteEndElement();
}
// Write out .
writer.WriteEndElement();
// Write out .
writer.WriteEndElement();
// Save the string in the cache (cache for 1.5 hours).
Cache.Insert("RssFeed", sw.ToString(), null,
DateTime.Now.AddHours(1.5), TimeSpan.Zero);
writer.Close();
}
// Write out the cached value.
Response.Write(Cache["RssFeed"].ToString());
Figure 5: An XmlTextWriter is used to syndicate content to a string. This string, which is cached, is then returned to the requesting client.
The code in Figure 5 starts by indicating that the returned content type is text/xml, and that it is encoded using 8-bit Unicode (UTF8). Next, a check is performed to see if there is an item named RssFeed in the cache. The RssFeed cache item contains the RSS feed's XML. If the XML is not in the cache, it needs to be regenerated. This begins by getting information about the Web site content and storing it in a DataTable. (The CreateDataSource method in Figure 5 simply returns a pre-populated DataTable; in your ASP.NET Web page you'd want to actually query the data store in which your content resides.)
Next, a StringWriter
is created and used as the backing store for the XmlTextWriter instance created on the next line. Following that,
the
After the for
loop the
If you visit the ASP.NET Web page through a browser you should see an XML document that corresponds to the RSS 2.0 specification (see Figure 6).
Figure 6: Visit an ASP.NET Web page through a browser to see an XML
document that corresponds to the RSS 2.0 specification.
Be Aware of Performance
In Figure 5, the RSS feed's XML is cached using the data cache. I chose to use the data cache because the cached value can be shared across pages in an ASP.NET Web application, so if the RSS needs to be parsed in some other page, it is accessible without having to recreate the XML from scratch. Furthermore, items in the data cache can be given cache dependencies on external files. So, if you have a file that is automatically updated when your system updates its content, this file can be used as a cache dependency so that the emitted RSS is always up-to-date with the current content.
An alternative approach to caching with the data cache would be to use output caching. Employing output caching to the code in Figure 5 would simplify the code a little bit, removing the need for:
- inserting the XML into the cache;
- checking to see if the RssFeed cache item exists; and
- using a StringWriter (instead the XmlTextWriter could use the Response.OutputStream as the backing store).
For a more in-depth discussion on the different caching options available in ASP.NET be sure to read Scott McFarland's article "Caching with ASP.NET" at http://aspnet.4guysfromrolla.com/articles/022802-1.aspx.
If a significant number of visitors subscribe to your
site's RSS feed, you'll quickly find that the ASP.NET Web page that generates
the RSS feed will become one of the most requested Web pages. This is because
RSS aggregators typically request the file once every hour, or once every few
hours, depending on the RSS aggregator being used and your syndication feed's
To reduce the impact of the increase in requests you will hopefully receive, consider employing both caching and HTTP compression techniques. The caching can be accomplished using either output caching or the data cache, as described before. HTTP compression improves the outgoing bandwidth by first compressing the Web server's output stream and sending this compressed version to the client. The client, then, can decompress the received content. HTTP compression will typically be able to reduce the size of an RSS file anywhere between 20% to 40%. HTTP compression can be enabled natively in some versions of IIS, or can be provided through a third-party component, like Pipeboost, httpZip, and XCompress. (A thorough discussion of implementing HTTP compression is beyond the scope of this article.)
Once you have created and validated an RSS feed, you're ready to share it with the world. Grab one of those little orange icons (see Figure 1), slap it up on your homepage, and link it to your RSS feed.
Happy Programming!
The sample code in this article is available for download.
Speaker, author, and teacher, Scott Mitchell is the editor and founder of 4GuysFromRolla.com, one of the largest ASP resource sites on the Web. He has been avidly using and writing about Active Server Pages since January 1998. He's authored several hundred ASP-related articles on 4Guys along with numerous beginner- and advanced-level books on Active Server Pages and ASP.NET. Scott can be reached at mailto:mitchell@4guysfromrolla.com. You can find his weblog at http://ScottOnWriting.NET.
What's the other Guy up To?
Interested in which version of RSS other Web sites are syndicating their content? Syndic8.com, which provides syndication feeds for thousands of news services, offers a statistical breakdown of RSS versions used at mailto:www.syndic8.com/stats.php?Section=rss. The results? About two-thirds of the sites use RSS 0.91, RSS 0.92, or RSS 2.0 (the versions that don't adhere to the RDF standard), while the remaining third uses RSS 1.0.
Trust but Verify
Before publishing your RSS feed on your Web site, be sure to take a moment to verify that you're syndicating your content using valid RSS. There are online validators, such as The Feed Validator: http://feedvalidator.org, which can help to ensure your RSS feed is valid.