ASP.NET Tip: Creating an Atom XML Feed

An easy way to promote your site and to attract more visitors is to provide a news feed. Feeds can be read by a variety of programs, including FeedDemon, Mozilla, and the upcoming Internet Explorer 7.0. Many sites continue to use RSS (Real Simple Syndication), but RSS was never a defined standard. Atom, the replacement for RSS, is quickly being adopted by many of the blogging software makers, although most of them still provide support for RSS as well.

This tip shows you how to produce an Atom XML feed using a database table. It is based on the following sample of the Atom syndication format, which is available on this page:

<?xml version="1.0" encoding="utf-8"?>
<feed >

   <title>Example Feed</title>
   <link href="http://example.org/"/>
   <updated>2003-12-13T18:30:02Z</updated>
   <author>
      <name>John Doe</name>
   </author>
   <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>

   <entry>
      <title>Atom-Powered Robots Run Amok</title>
      <link href="http://example.org/2003/12/13/atom03"/>
      <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
      <updated>2003-12-13T18:30:02Z</updated>
      <summary>Some text.</summary>
   </entry>

</feed>

The entry tag section is the one that will repeat for each article you want to syndicate. Most of the information is fairly self-explanatory, and the atomenabled.org site provides other tags that let you further document your articles. A few of these tags may require a bit of coding on your part, however.

The first tag you see is the updated tag, which shows the time in the standard Internet format. The format shows “Zulu” time, which is a military/aviation name for Greenwich Mean Time. Although you could manually create this format, some built-in date/time formats will get you most of the way to there.

The first format string is a lowercase s, which generates the date and time in this format:

2000-08-17T16:32:32

The second option is a lowercase u, which generates the date and time in this format:

2000-08-17 23:32:32Z

The second option also translates the local time to the “universal” time. Because you need both the T and the Z, as well as the timezone conversion, you can use the ToUniversalTime method of the DateTime class, the lowercase s format, and simply append a Z to the string. (You can learn more about the various built-in time/date formats by looking at the ToString method of the DateTime class in the MSDN documentation.)

The next tag is the ID tag on both the feed and the entry levels. This is easy to create in .NET by using a globally unique identifier (GUID). The important thing to remember is that this unique value should persist for this entry, meaning that you can’t just generate random ones each time you display the feed. In my case, I store the unique identifier in the database so it always displays the same value. If you don’t do that, it will cause the various newsreaders to display changes to an article as a new article, which defeats the purpose of sending a feed. If you keep the same ID, the newsreader will usually just indicate that the article has changed but not create a new entry.

Here’s the code I use to generate my Atom feed:

protected void Page_Load(object sender, EventArgs e)
{
   // Code to retrieve DataTable of news articles
   StringBuilder feed = new StringBuilder();

   feed.Append("<?xml version="1.0" encoding="utf-8" ?>n");
   feed.Append("<feed xmlns="http://www.w3.org/2005/Atom">");
   feed.AppendFormat("<title>{0}</title>", titlegoeshere);
   feed.Append("<link href="http://www.northcomp.com/" />");
   feed.AppendFormat("<updated>{0:s}Z</updated>",
                     lastupdatedDateTime.ToUniversalTime());
   feed.Append("<author><name>Eric Smith</name></author>");
   feed.AppendFormat("<id>urn:uuid:{0}</id>",
                     uniqueIDForFeedThatStaysSame);

   foreach (DataRow dr in dt.Rows)
   {
      feed.AppendFormat("<entry><title>{0}</title>",
                        dr["Title"]);
      feed.AppendFormat("<link>http://www.northcomp.com/about/
                         news.aspx?id={0}</link>",
                         dr["pkArticleID"]);
      feed.AppendFormat("<id>urn:uuid:{0}</id>",
                        dr["AtomID"]);
      feed.AppendFormat("<summary>{0}</summary>",
                        dr["Synopsis"]);
      feed.AppendFormat("<updated>{0:s}Z</updated>",
                        Convert.ToDateTime(dr["ReleaseDate"]).
                        ToUniversalTime());
      feed.Append("</entry>");
   }
   feed.Append("</feed>");

   Response.Clear();
   Response.ContentType = "text/xml";
   Response.Write(feed.ToString());
   DB.Close();

}

The ASPX portion of this page should contain only the Page directive at the top of the file. My table contains an identity field called pkArticleID, which provides the unique link for each news entry. The AtomID field is a unique identifier, and the Title, Synopsis, and ReleaseDate fields are self-explanatory. At the feed level, I use the latest news article’s release date as the updated value, as the data table I retrieve is sorted in reverse order by date—I just pull the first ReleaseDate field and put it in that field.

About the Author

Eric Smith is the owner of Northstar Computer Systems, a web-hosting company based in Indianapolis, Indiana. He is also a MCT and MCSD who has been developing with .NET since 2001. In addition, he has written or contributed to 12 books covering .NET, ASP, and Visual Basic. Send him your questions and feedback via e-mail at questions@techniquescentral.com.

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read