Sunday, March 05, 2006

Managing ASHX files

In the web application that I am working on, a web page is composed of several user controls. The composition happens in the runtime and is driven by metadata stored in a database. As reconstructing a web page during postback is quite expensive, I opted to out-of-band AJAX requests for all our asyncronous requests.

Consequently, there is a growing number of ASPX created solely to handle AJAX requests in our web project. Initially, I created a folder called "Handlers", containing all ASPXs that handle out-of-band AJAX request, separating from the normal ASPX files. I also suffix the file name with Handler, like 'LookupHandler.aspx' to further separate between ASPX handler and normal ASPX.

I am aware about ASHX as an option to handle out-of-band AJAX request instead of using ASPX. A lot of people say that ASHX is simpler, therefore it should run faster. I need to see a benchmark to support this though.

Although ASHX seems to give some performance benefit over ASPX, I was initially discouraged to use this in our projects or even recommend this approach to my fellow developers. ASHX is not supported by VS.NET 2003. There is no file template to begin with, and the worst is there is no Intellisense support. This thought revolved around me until after some time I got spare time to do more experiment with ASHX.

Not to my surprise, ASHX supports code behind. But the code behind just does not work as seamlessly as ASPX. I can't make the code behind file a child of the ASHX file in the web projects like:


ContactHandler.ashx
|
+- ContactHandler.ashx.cs


This does not work.

What I can do is to structure the ASHX and code behind at the same level. Not as nice as the way ASPX is structured, but still acceptable.

ContactHandler.ashx
ContactHandler.ashx.cs

To have the ASHX working properly with code behind, we have to add class attribute in the declaration:

ContactHandler.ashx only contains 1 line:


<%@ Webhandler language="c#" class="JLTi.iClaims.Handler.LookupHandler" %>




ContactHandler.ashx.cs contains the actual code to handle out-of-band AJAX request:

using System;
using
System.Web;

namespace
Experiment
{
public class ContactHandler : System.Web.IHttpHandler
{
#region IHttpHandler Members

public void ProcessRequest(HttpContext context)
{
context.Response.Write(
"Hello World from ASHX");
context.Response.End();
}

public bool IsReusable
{
get
{
return true;
}
}

#endregion
}
}



A better way to manage ASHX is to put the code behind file in another project (a class library) like:


Experiment.Handler
|
+-- ContactHandler.cs

Experiment.Web
|
+-- Handlers
|
+-- ContactHandler.ashx


In the above example, the ASHX file is put in the folder 'Handlers' inside the web project and the code behind file is put in a separate class library project. By structuring this way, we can easily version, share, and reuse the code in the code behind among several solutions.