Http Handlers applied – Rss Feed
RSS Feeds are very popular these days.
Recently, I found myself in the need of using a rss feed for a “Joke of the day” web part. The tricky side of the business was that I had to provide only one like in the rss feed – the joke for the current day. Many options came into my mind, but the most elegant was by far the HttpHandler one.
An HttpHandler is an independent unit that manages the server response for a given situation: for example, a specific file extension. In my case, what I need was for the web application to create a rss file “on the fly” when a user requested a certain url. The url was http://mycompany.com/RssFeed/jokes.rss and the trick - the file didn’t even exist :) . When the url was requested, I had to tell the application that a rss file (stream) had to be generated and passed to the client.
How is this done? First of all, you need a class that generated the feed. This class needs to implement the IhttpHandler interface. What this class does is to read one joke from a data source (xml, database etc) and output it to the browser as a rss file. You can put this class in a ClassLibrary project, because you will need the dll. Here is the code:
namespace MDL.RSSLibDLL
{
public class RssHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context) // this is the function that needs to be implemented. It comes, by dfault, with the Context of the user in the application that it handles
{
// Get the file name from the requested url
string fileName = Path.GetFileName(context.Request.Path); // the rss file that the user wants
//generally, you want to cache your rss files
string cachedChan = context.Cache[fileName] as String;
if (cachedChan == null)
{
// The file is not in the cache
string profileFolder = ConfigurationSettings.AppSettings["rssProfileFolder"];
//get the rss profile – the phyisical structure
if (profileFolder == null)
{
context.Response.StatusCode = 404;
context.Response.End();
return;
}
// Verify that you actually have a profile for the requested feed(a source rss file to read the structure from )
string profilePath = profileFolder + "" + fileName;
if (!File.Exists(profilePath))
{
context.Response.StatusCode = 404;
context.Response.End();
return;
}
// create the rss response
RssChannel chan = new RssChannel(profilePath, DateTime.Now);
cachedChan = chan.GetResponse();
double cacheTimeout;
string appCacheTimeout = ConfigurationSettings.AppSettings["cacheTimeout"];
if (appCacheTimeout == null)
cacheTimeout = 30;
else
cacheTimeout = double.Parse(appCacheTimeout);
context.Cache.Insert(fileName, cachedChan, null, DateTime.Now.AddMinutes(cacheTimeout), TimeSpan.Zero);
}
context.Response.ContentType = "text/xml";
context.Response.Write(cachedChan); // output the rss to the browser
}
public bool IsReusable
{
get
{
return true;
}
}
}
internal class RssChannel //my class that implements a Rss feed item
{
private string _title;
private string _link;
private string _description;
private string _language;
private string _date;
private string _profilePath; //resulting RSS structure
private ArrayList _items;
public RssChannel(string profilePath, DateTime date)
{
_profilePath = profilePath;
_date = date.Month.ToString() + "/" + date.Day.ToString();
Load();
}
public string Title
{
get { return (_title); }
set { _title = value; }
}
public string Link
{
get { return (_link); }
set { _link = value; }
}
public string Description
{
get { return (_description); }
set { _description = value; }
}
public string Language
{
get { return (_language); }
set { _language = value; }
}
public RssItem this[int index]
{
get
{
if (index < _items.Count)
return ((RssItem)_items[index]);
return (null);
}
}
public string GetResponse()
{
XmlElement workNode;
XmlElement itemNode;
RssItem currentItem;
XmlDocument rssDocument = new XmlDocument();
// Create the rss document node and set the its attributes
XmlElement docNode = rssDoc.CreateElement("rss");
XmlAttribute attr = rssDoc.CreateAttribute("version");
attr.Value = "2.0";
docNode.Attributes.Append(attr);
rssDoc.AppendChild(docNode);
// Create the channel element and its children
XmlElement chanNode = rssDoc.CreateElement("channel");
docNode.AppendChild(chanNode);
workNode = rssDoc.CreateElement("title");
workNode.InnerText = _title;
chanNode.AppendChild(workNode);
workNode = rssDoc.CreateElement("link");
workNode.InnerText = _link;
chanNode.AppendChild(workNode);
workNode = rssDoc.CreateElement("description");
workNode.InnerText = _description;
chanNode.AppendChild(workNode);
workNode = rssDoc.CreateElement("language");
workNode.InnerText = _language;
chanNode.AppendChild(workNode);
// Add item nodes to the channel
for (int index = 0; index < _items.Count; index++)
{
currentItem = (RssItem)_items[index];
itemNode = rssDoc.CreateElement("item");
chanNode.AppendChild(itemNode);
workNode = rssDoc.CreateElement("joke");
workNode.InnerText = currentItem.Joke;
itemNode.AppendChild(workNode);
workNode = rssDoc.CreateElement("date");
workNode.InnerText = currentItem.Date;
itemNode.AppendChild(workNode);
}
return (rssDoc.OuterXml);
}
private void Load()
{
_items = new ArrayList();
// Set channel properties from the profile:
_title = profile.SelectSingleNode("rss/channel/title").InnerText;
_link = profile.SelectSingleNode("rss/channel/link").InnerText;
_description = profile.SelectSingleNode("rss/channel/description").InnerText;
_language = profile.SelectSingleNode("rss/channel/language").InnerText;
string _source = profile.SelectSingleNode("rss/channel/source").InnerText;
// Retrieve items from the joke source
// input your code depending on the datasource
…
RssItem currentItem = new RssItem( /*joke text field*/,/*joke date field*/);
_items.Add(currentItem);
…
}
// internal class that implements the Joke object
internal class RssItem
{
private string _joke;
private string _date;
internal RssItem(string joke, string date)
{
_joke = joke;
_date = date;
}
public string Joke
{
get { return (_joke); }
set { _joke = value; }
}
public string Date
{
get { return (_date); }
set { _date = value; }
}
}
}
This class uses 3 (or more) pieces of information that you need to provide from an external source:
- The rss profile file – the file with the rss structure
- The cache timeout value
- The data information – xml file path, database connection string, select query etc
My code used an xml file that had jokes for all the days of the year. What I did was to get the current date and then read from the xml file the corresponding joke.
You can pass this information in a very elegant way – the web.config file. The web config file of the web application that will serve the rss. This web application can have no pages at all – that is the beauty of it J. What you need to do for the web application is:
- Put this in the web.config:
The HttpHandlers section tells the application that the handler for the rss files is the RssHandler class.
- Add the Classlibrary application dll in the bin directory
- Tell IIS that you want to handle the rss file requests differently.
![]()
You can copy the executable path from another extension mapping.
Now all the requests for a rss file will be handled by the RssHandler class. The beauty of it is that you can particularize the class for different rss files.
Here is a sample structure for the rss file:
![]()
If you build this solution and install it on your localhost, if you then go to http://localhost/my_app_name/jokes.rss you should be shown a feed with one item for the corresponding date.








Recent Comments
Starting form the sample I mentioned
Thanks for posting this. It sav
The left image does not overlap t
Was Looking for the "inline" and "at