Video icon 64
Learning to code? Skill up faster with our practical video courses. Start your free trial today.
Advertisement

How to Build an RSS Feed with ASP.NET

by

Over the course of this tutorial, we’ll review how to create an RSS Feed with the ASP.NET framework. Having an RSS feed for your site has become a necessity in recent years. With blogs or news sites being updated frequently, and with the vast amount of blogs and news websites out there, RSS has allowed readers to keep up with new content without being forced to visit them. Once you've completed this tutorial, you'll know how to create an RSS feed with ASP.NET, and how to render XML documents on ASP.NET Web pages.


Step 0: RSS 2.0 Introduction

RSS is a web content syndication format. It stands for "Really Simple Syndication," and is written in XML. All RSS files must conform to the XML 1.0 specification, as published by the World Wide Web Consortium (W3C). With RSS, it is possible to distribute up-to-date web content from one web site to thousands of others around the world. To simplify the term, RSS allows fast browsing for news and updates.

The syntax rules of RSS 2.0 are quite simple, though strict. Here is a simple RSS document:

<?xml version="1.0" encoding="utf-8" ?>
<rss version="2.0">
  <channel>
    <title>Your Website Name</title>
    <link>http://www.yourdomain.com</link>
    <description>Free RSS Tutorial</description>
    <item>
      <title>First Article</title>
      <link>http://www.yourdomain.com/article.aspx?ID=1</link>
      <description>The description of the first article.</description>
    </item>
    <item>
      <title>Second Article</title>
      <link>http://www.yourdomain.com/article.aspx?ID=2</link>
      <description>The description of the second article.</description>
    </item>
  </channel>
</rss>

The first line in the document - the XML declaration - defines the XML version and the character encoding used in the document. In this case, the document conforms to the 1.0 specification of XML, and uses the utf-8 character set. The next line is the RSS declaration, which identifies that this is, in fact, an RSS document (more specifically, RSS version 2.0).

The next line contains the <channel> element. This element is used to describe the RSS feed. The <channel> element has three required child elements:

  • <title> - Defines the title of the channel (e.g. Your Website name)
  • <link> - Defines the hyperlink to the channel (e.g. http://www.yourdomain.com)
  • <description> - Describes the channel (e.g. Free RSS Tutorial)

Each <channel> element can have one or more <item> elements. Each <item> element defines an article or "story" within the RSS feed.

The <item> element requires three child elements:

  • <title> - Defines the title of the item (e.g. First Article)
  • <link> - Defines the hyperlink to the item (e.g. http://www.yourdomain.com/article.aspx?ID=1)
  • <description> - Describes the item (e.g. The description of the first article)

When viewed in Firefox, the RSS document above should look similar to:

RSS document

Step 1: Getting Started

To follow this tutorial, imagine that you work as a web developer, and are building a news website where all of the news stories are stored in Microsoft's SQL Server database. Specifically, the articles are stored in a table called News, which contains the following fields:

  • ArticleID - an auto-increment primary key integer field uniquely identifying each article
  • Title - a nvarchar(256), specifying the title of the article
  • Author - a nvarchar(50), specifying the author of the article
  • Description - a nvarchar(500), providing a more in-depth description of the article
  • DatePublished - a datetime, indicating the date the article was published

Note that there might be other fields in the News table, but those listed above are the only ones we are interested in using -- at least for the purposes of an RSS feed.

We'll use Visual Studio to finish the example. If you don’t have the full version of VS, you can grab the free Express Edition.


Step 2: Creating an rss.aspx Page

Our next step is to create an ASP.NET Web page (rss.aspx) that will display a list of the most recent news items as a properly formatted RSS 2.0 document. In Solution Explorer, right-click the project name, and then click Add New Item. In thia dialog box, under Visual Studio installed templates, click Web Form.

Add New Page

 In the Name box, type a name for the new Web page (rss.aspx), and then click Add. The new ASP.NET web page (rss.aspx) is created and displayed, accordingly.

Because we want the rss.aspx page to produce XML output, the first thing that we must do is remove all HTML markup or web controls from the page, and then set the ContentType property of @page directive to "text/xml".

After clearing all HTML markup from rss.aspx page, add a Repeater control into the page. We'll use Repeater control to render RSS document on rss.aspx page.

Here is the source view of the rss.aspx page, after we've made some changes:

<%@ Page Language="C#" ContentType="text/xml" AutoEventWireup="true" CodeBehind="rss.aspx.cs" Inherits="NettutsTutorial2.rss" %>

<asp:Repeater ID="RepeaterRSS" runat="server">
</asp:Repeater>

Step 3: Setup The Connection String

Next, we want to setup the connection string of the data source, within the Web.config file. By saving the connection string information, we'll avoid having to hard-code it in the code-behind file. This simplifies things, if the connection string information changes in the future. Place it in the <connectionStrings> section under configuration element, like so:

<connectionStrings>
  <add name="ConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Nettuts.mdf;Integrated Security=True;User Instance=True"
   providerName="System.Data.SqlClient" />
 </connectionStrings>

We will access this information from the code-behind file later when we want to retrieve data from database.


Step 4: Removing Illegal Characters from the XML Document

Some characters have special meaning in XML. If you place a character, such as "<", inside an XML element, it will generate an error, because the parser interprets it as the start of a new element. To avoid this error, replace the "<" character with its entity reference (&lt;).

There are five predefined entity references in XML:

&lt; < less than
&gt; > greater than
&amp; & ampersand 
&apos; ' apostrophe
&quot; " quotation mark

To avoid our RSS feed producing an error, we have to change all illegal characters in an RSS document with their entity references. Add the following code into the code-behind file of the rss.aspx page (rss.aspx.cs):

protected string RemoveIllegalCharacters(object input)
{
    // cast the input to a string
    string data = input.ToString();      

    // replace illegal characters in XML documents with their entity references
    data = data.Replace("&", "&amp;");
    data = data.Replace("\"", "&quot;");
    data = data.Replace("'", "&apos;");
    data = data.Replace("<", "&lt;");
    data = data.Replace(">", "&gt;");

    return data;
}

The RemoveIllegalCharacters() function performs a few simple string replacements, if needed. We will call this function from the rss.aspx page shortly.


Step 5: Retrieving Data from the Database

Add the following code into the Page_Load event handler:

protected void Page_Load(object sender, EventArgs e)
{
    // Get connection string from the web.config file
    string connString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;

    // Create SqlConnection object
    SqlConnection sqlConn = new SqlConnection();
    sqlConn.ConnectionString = connString;

    // SQL query to retrieve data from database
    string sqlQuery = "SELECT TOP 10 ArticleID, Title, Author, Description, DatePublished FROM News ORDER BY DatePublished DESC";

    // Create SqlCommand object
    SqlCommand cmd = new SqlCommand();
    cmd.Connection = sqlConn;
    cmd.CommandType = CommandType.Text;
    cmd.CommandText = sqlQuery;

    // open connection and then binding data into RepeaterRSS control
    sqlConn.Open();
    RepeaterRSS.DataSource = cmd.ExecuteReader();
    RepeaterRSS.DataBind();
    sqlConn.Close();
}

The code above will attempt to retrieve the ten most recent news items from your database. It will then bind them to a Repeater control (RepeaterRSS) when the page is loaded.


Step 6: Rendering Data

This is our last step. It's time to render items from the News table into an appropriate RSS 2.0 syndication file. The simplest and quickest way to display the database data as XML is to use a Repeater control (RepeaterRSS). Specifically, the Repeater will display the <rss>, <channel>, and Web site related element tags in its HeaderTemplate and FooterTemplate templates, and the <item> elements in the ItemTemplate template. Don't forget to call the helper RemoveIllegalCharacters() function to replace unwanted characters from the string output.

The following is the HTML portion of our ASP.NET Web page (rss.aspx):

<%@ Page Language="C#" ContentType="text/xml" AutoEventWireup="true" CodeBehind="rss.aspx.cs" Inherits="NettutsTutorial2.rss" %>

<asp:Repeater ID="RepeaterRSS" runat="server">
        <HeaderTemplate>
           <rss version="2.0">
                <channel>
                    <title>Name of the Website</title>
                    <link>http://www.yourdomain.com</link>
                    <description>
                    Short description of the website.
                    </description>
        </HeaderTemplate>
        <ItemTemplate>
            <item>
                <title><%# RemoveIllegalCharacters(DataBinder.Eval(Container.DataItem, "Title")) %></title>
                <link>http://www.yourdomain.com/news.aspx?ID=<%# DataBinder.Eval(Container.DataItem, "ArticleID") %></link>
                <author><%# RemoveIllegalCharacters(DataBinder.Eval(Container.DataItem, "Author"))%></author>
                <pubDate><%# String.Format("{0:R}", DataBinder.Eval(Container.DataItem, "DatePublished"))%></pubDate>
                <description><%# RemoveIllegalCharacters(DataBinder.Eval(Container.DataItem, "Description"))%></description>
        </item>
        </ItemTemplate>
        <FooterTemplate>
                </channel>
            </rss>  
        </FooterTemplate>
</asp:Repeater>

The first thing worth noting here is that the rss.aspx file above contains only the Repeater control (RepeaterRSS), and no other HTML markup or Web controls. This is because we want the page to emit nothing but XML output. We set the ContentType of the @Page directive to "text/xml" to indicate that the output of the rss.aspx page is an XML document.

In the HeaderTemplate template of the Repeater control, we place the <rss> and <channel> elements.

Next, in the ItemTemplate, we place the <item> elements, which contain the <title>, <link>, <author>, <pubDate>, and <description> elements, as the place for database fields. We call the RemoveIllegalCharacters() function when adding the Title, Author, and Description database fields to the XML output. Remember, this function simply replaces any illegal XML characters with their  entity references.

Finally, the DatePublished database field, entered into the <pubDate> element, is formatted using the String.Format method. The standard format specifier, R, formats the DatePublished value appropriately according to RFC 822, Date and Time Specification. This starts with an optional three-letter day abbreviation and comma, followed by a required day, the three-letter abbreviated month, and then the year, followed by a time with the time-zone name, such as Thu, 04 Nov 2010 20:50:26 GMT.


The Result

And there we have it! With minimal effort, we've created a custom RSS feed for an ASP.NET application.

The Resulting Feed

The Complete Code

The rss.aspx File

<%@ Page Language="C#" ContentType="text/xml" AutoEventWireup="true" CodeBehind="rss.aspx.cs" Inherits="NettutsTutorial2.rss" %>

<asp:Repeater ID="RepeaterRSS" runat="server">
        <HeaderTemplate>
           <rss version="2.0">
                <channel>
                    <title>Name of the Website</title>
                    <link>http://www.yourdomain.com</link>
                    <description>
                    Short description of the website.
                    </description>
        </HeaderTemplate>
        <ItemTemplate>
            <item>
                <title><%# RemoveIllegalCharacters(DataBinder.Eval(Container.DataItem, "Title")) %></title>
                <link>http://www.yourdomain.com/news.aspx?ID=<%# DataBinder.Eval(Container.DataItem, "ArticleID") %></link>
                <author><%# RemoveIllegalCharacters(DataBinder.Eval(Container.DataItem, "Author"))%></author>
                <pubDate><%# String.Format("{0:R}", DataBinder.Eval(Container.DataItem, "DatePublished"))%></pubDate>
                <description><%# RemoveIllegalCharacters(DataBinder.Eval(Container.DataItem, "Description"))%></description>
        </item>
        </ItemTemplate>
        <FooterTemplate>
                </channel>
            </rss>  
        </FooterTemplate>
</asp:Repeater>

The rss.aspx.cs File

using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Data.SqlClient;

namespace NettutsTutorial2
{
    public partial class rss : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            // Get connection string from web.config file
            string connString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;

            // Create SqlConnection object
            SqlConnection sqlConn = new SqlConnection();
            sqlConn.ConnectionString = connString;

            // SQL query to retrieve data from database
            string sqlQuery = "SELECT TOP 10 ArticleID, Title, Author, Description, DatePublished FROM News ORDER BY DatePublished DESC";

            // Create SqlCommand object
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = sqlConn;
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = sqlQuery;

            // open connection and then binding data into RepeaterRSS control
            sqlConn.Open();
            RepeaterRSS.DataSource = cmd.ExecuteReader();
            RepeaterRSS.DataBind();
            sqlConn.Close();
        }

        protected string RemoveIllegalCharacters(object input)
        {
            // cast the input to a string
            string data = input.ToString();

            // replace illegal characters in XML documents with their entity references
            data = data.Replace("&", "&amp;");
            data = data.Replace("\"", "&quot;");
            data = data.Replace("'", "&apos;");
            data = data.Replace("<", "&lt;");
            data = data.Replace(">", "&gt;");

            return data;
        }
    }
}

The Web.config File

<?xml version="1.0"?>
<configuration>
	<configSections>
		<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
			<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
				<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
				<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
					<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
					<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
					<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
					<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
				</sectionGroup>
			</sectionGroup>
		</sectionGroup>
	</configSections>
	<appSettings/>
	<connectionStrings>
		<add name="ConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Nettuts.mdf;Integrated Security=True;User Instance=True" providerName="System.Data.SqlClient"/>
	</connectionStrings>
	<system.web>
		<!-- 
            Set compilation debug="true" to insert debugging 
            symbols into the compiled page. Because this 
            affects performance, set this value to true only 
            during development.
        -->
		<compilation debug="true">
			<assemblies>
				<add assembly="System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
				<add assembly="System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
				<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
				<add assembly="System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
			</assemblies>
		</compilation>
		<!--
            The <authentication> section enables configuration 
            of the security authentication mode used by 
            ASP.NET to identify an incoming user. 
        -->
		<authentication mode="Windows"/>
		<!--
            The <customErrors> section enables configuration 
            of what to do if/when an unhandled error occurs 
            during the execution of a request. Specifically, 
            it enables developers to configure html error pages 
            to be displayed in place of a error stack trace.

        <customErrors mode="RemoteOnly" defaultRedirect="GenericErrorPage.htm">
            <error statusCode="403" redirect="NoAccess.htm" />
            <error statusCode="404" redirect="FileNotFound.htm" />
        </customErrors>
        -->
		<pages>
			<controls>
				<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
				<add tagPrefix="asp" namespace="System.Web.UI.WebControls" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
			</controls>
		</pages>
		<httpHandlers>
			<remove verb="*" path="*.asmx"/>
			<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
			<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
			<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" validate="false"/>
		</httpHandlers>
		<httpModules>
			<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
		</httpModules>
	</system.web>
	<system.codedom>
		<compilers>
			<compiler language="c#;cs;csharp" extension=".cs" warningLevel="4" type="Microsoft.CSharp.CSharpCodeProvider, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
				<providerOption name="CompilerVersion" value="v3.5"/>
				<providerOption name="WarnAsError" value="false"/>
			</compiler>
		</compilers>
	</system.codedom>
	<!-- 
        The system.webServer section is required for running ASP.NET AJAX under Internet
        Information Services 7.0.  It is not necessary for previous version of IIS.
    -->
	<system.webServer>
		<validation validateIntegratedModeConfiguration="false"/>
		<modules>
			<remove name="ScriptModule"/>
			<add name="ScriptModule" preCondition="managedHandler" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
		</modules>
		<handlers>
			<remove name="WebServiceHandlerFactory-Integrated"/>
			<remove name="ScriptHandlerFactory"/>
			<remove name="ScriptHandlerFactoryAppServices"/>
			<remove name="ScriptResource"/>
			<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
			<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
			<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
		</handlers>
	</system.webServer>
	<runtime>
		<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
			<dependentAssembly>
				<assemblyIdentity name="System.Web.Extensions" publicKeyToken="31bf3856ad364e35"/>
				<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
			</dependentAssembly>
			<dependentAssembly>
				<assemblyIdentity name="System.Web.Extensions.Design" publicKeyToken="31bf3856ad364e35"/>
				<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="3.5.0.0"/>
			</dependentAssembly>
		</assemblyBinding>
	</runtime>
</configuration>

Conclusion

Creating an RSS feed with ASP.NET is quite simple, isn't it? We only need to understand the RSS 2.0 specification. Beyond that, by using the .NET Repeater control, we can render items from a database into the RSS document. Most content management systems will have this capability by default. However, if you're a developer, and are building an ASP.NET website from scratch, you now have the skills to build your own custom feed.

Happy Coding!

Advertisement