Wednesday, November 19, 2008

IHttp Handler Creation & Caching

We want to create a page on our site returning an XML file to the visitor.

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:


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.


So, 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




Yes, thats correct, just one single line. It says the class for our Webhandler is called Arif.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 Arif.RSSHandler and therefore instantiates an object of that class.

Now lets have a look at the handler class:


RSSHandler.cs

namespace Arif
{
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.

2 comments:

  1. good post for ammeture asp.netter

    ReplyDelete
  2. generic handler gives a lot of performance boost. it simple to use but really powerful. thanks arif bhai. good one.

    ReplyDelete