Aug
30
2006
Creating an ASHX handler in ASP.NET
Posted by admin under
ASP.NET articles
Today a typical web application is not only about serving HTML to browsers, but also serving XML and other types of content. Say you are creating a RSS feed for your site, for example. RSS should be presented as XML and I will cover that specific case in another article (will be available in related articles when posted) but this particular article will just show you the basics of putting an ASHX page handler up.
Problem
We want to create a page on our site returning an XML file to the visitor.
Possible solution
There are lots of suggestions creating a regular ASPX page (say rss.aspx) and in Page_Load use Response.Write to return the XML. Example:
public class RSS : System.Web.UI.Page
{
private void Page_Load(object sender, System.EventArgs e)
{
Response.ContentType = "text/xml";
Response.ContentEncoding = Encoding.UTF8;
string sXml = BuildXMLString(); //not showing this function,
//but it creates the XML string
Response.Write( sXml );
Response.End();
}
}
This will indeed work, and since it is a regular page you have great options to improve performance just with some page declarations at the top of the rss.aspx file:
<!--OutputCache Duration="600" VaryByParam="None"-->
Now what's wrong with it? Well, basically nothing, but it is a fact that our page class (RSS) inherits from System.Web.UI.Page and that page handler is indented for serving aspx pages (i.e WebForms) and includes a lot of overhead not needed for just serving a simple XML file.
Alternate solution
There are other solutions. You can create your own page handlers, and you can even map your own file extentions to your handlers, for example you could invent your own file extention called .myspecialrss. Now you can (with some configurations settings in IIS/web.config) map all requests to whatever.myspecialrss to your own special file handler. However, needing to do some configurations are never fun to do - if even possible in a shared hosting scenario, therefore Microsoft has kindly given us a special filetype .ASHX which maps to the ASP.NET engine.
Now what we are going to is is create a file - rss.ashx - which when called returns the same XML as in the example above. If you have forgotten why - the ashx handler doesn't give us all that overhead as a .aspx request does.
So, start off by creating
rss.ashx
<!--WebHandler Language="C#" Class="KBMentor2.RSSHandler"-->
Yes, thats correct, just one single line. It says the class for our Webhandler is called KBMentor2.RSSHandler, so we will now create that class. To put it simple - what happens is that when the request for rss.ashx comes to the ASP.NET engine it reads the rss.ashx file, sees that the class is KBMentor2.RSSHandler and therefore instantiates an object of that class.
Now lets have a look at the handler class:
RSSHandler.cs
namespace KBMentor2
{
using System;
using System.IO;
using System.Web;
public class RSSHandler : IHttpHandler
{
public void ProcessRequest (HttpContext context)
{
context.Response.ContentType = "text/xml";
context.Response.ContentEncoding = System.Text.Encoding.UTF8;
string sXml = BuildXMLString(); //not showing this function,
//but it creates the XML string
context.Response.Cache.SetExpires(DateTime.Now.AddSeconds(600));
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Write( sXml );
}
public bool IsReusable
{
get { return true; }
}
}
}
And there you have it. Looks pretty much like the first code we created, doesn't it? As for caching, you can solve it by accessing the Cache object from your code, see the context.Response.Cache calls.