HttpHandler Hacking
I’m developing an ASP.NET application that utilizes an Ajax library called Ajax.Net Professional. This library allows you to quickly create the server side code and client javascript libraries needed for ajax applications. Please click the link to learn more. It’s pretty slick in that it dynamically creates ashx files that the aspx page includes and references. Entries such as the following are inserted in the aspx content when a page is requested by the client:
<script
type="text/javascript" src="/CVRMS/ajaxpro/core.ashx">
</script>
These ashx requests are handled on the server side by adding the following to your web.config file:
<httpHandlers>
<add
verb="POST,GET"
path="ajaxpro/*.ashx"
type="AjaxPro.AjaxHandlerFactory, AjaxPro"/>
</httpHandlers>
This tells the server to pass requests that match the path description to the handler factory designated by the type value. This is somewhat similar to servlet filters and mappings found in J2EE application servers.
The Problem(or, when the man is keeping you down)
A problem occurs when you are not allowed to add an httpHandler definition to your web.config file. You can be locked out if httpHandlers are defined as “machineOnly” in the machine.config file. This seems to be the case in some hosted environments that support a number of diverse ASP.NET applications. The reasoning for this is a topic for another discussion.
So, what to do? The good news is that if you happen to have the ashx file you can define a webhandler for that page by inserting the following into the file:
<%@ WebHandler Language="C#" Class="Ajax.AjaxHandler" %>
This is all well and good, but there are two problems:
- We don’t have a physical file, it is created dynamically by the Ajax httpHandler!!!
- The Ajax httpHandlers that are provided by the AjaxPro library are created by a custom HttpHandlerFactory. This is a problem because the ashx files can only be handled by handlers that can be created by the default SimpleHandlerFactory, so one can’t directly place the AjaxPro handler or factory into the ashx directive.
Solution (or, what I did to get it to work for the time being)
The answer to the first issue is pretty obvious since we need this file to exist we can just create it. The reason we need the file to exist is that if it is only a dynamically created file created by the handler it will only be created if the correct handler is used, but the server won’t know to use that handler to create the file if the file itself doesn’t tell it to! So, to boot strap the process I created a dummy file named the same as the request (core.ashx) and place in this just the following:
<%@ WebHandler Language="C#" Class="Ajax.AjaxHandler" %>
Now the server will see the physical file, compile it, and since it sees the webhandler definition it will pass the request to the handler that I’ve defined. The handler can now do its thing….
But problem #2 is still there. We can’t use a custom HandlerFactory in this case. The obvious solution is to just create a new HttpHandler that can be created by the SimpleHandlerFactory. This is simple and needs to implement the IHttpHandler interface and have a default constructor. In order to keep session state the handler also needs to implement the IRequireSessionState interface (which is a marker interface only and has no methods). To finish off the solution I implement the ProcessRequest method as such:
public void ProcessRequest(HttpContext context_)
{
AjaxHandlerFactory factory = new AjaxHandlerFactory();
IHttpHandler handler =
factory.GetHandler(context_,
context_.Request.RequestType,
context_.Request.RawUrl,
context_.Request.PhysicalApplicationPath);
handler.ProcessRequest(context_);
factory.ReleaseHandler(handler);
}
The server will take the request, pull the physical file, compiles it, passes the control to my basic httpHandler which in turn creates the correct AjaxPro handler using the AjaxPro HandlerFactory and passes control finally to the correct handler.
There is the minor inconvenience of having to create this physical file, but it only needs to be done once for each ajax enabled class and will work well enough until I can provision my own machines to run my application.
I hope this long winded, convoluted explanation makes sense and I will attempt to clarify if anyone is confused…and please let me know if there is a better way to perform this trick as I’m still somewhat new to this crazy world of ASP.NET.


January 25th, 2006 at 5:46 pm
I am using ASP.NET 2.0 and trying to come up with a way to convert my .css files into .ashx files because the css has a path or 2 that need to be converted/modified at runtime. I bumped into your post while “Googling”, and was wondering if you had $.02 to share on the issue.
March 19th, 2006 at 1:38 am
I am trying to use your solution but I can’t get it to work. I am new to AJAX.Net and I can’t publish my website. Would you please send me the exact code for the ashx file and if I should remove httphandler section from web.config or not and if I need to do any other setup to get it to work. I am very confused about this and I lost lots of time trying to understand what to do.
Thanks a lot for your help with this.
Hany