Written by Brad Wilson
Published on February 26, 2004
Reader Rating:
Using Visual Studio .NET, you might come to believe that the .ASPX file is the heart of the execution of a page. Not so. Learn what happens when an .ASPX page gets executed, and learn how to bypass the use of .ASPX pages with HTTP Handlers.
The final source code is available here.
When using Visual Studio .NET in its ASP.NET visual design mode, it creates pages using two files: the ASPX file, which represents HTML layout interspersed with code; and the CS file, which represents what Microsoft calls "Code Behind".
What, exactly, happens when you create that ASPX file and then browse to it with your browser? At its core, the ASP.NET execution engine compiles the page into a class, which derives from the code behind class (which in turn derives directly or indirectly from the Page class). Then it injects the newly created class into the execution environment, instantiates it, and executes it.
This is quite a change from classic ASP. The old model interpreted script code, written in JavaScript or VBScript. There was no compiling in the traditional sense of the word, and your choice of languages was limited to those understood by the ASP interpreter.
ASP.NET, on the other hand, can accept code in any language that is compatible with the .NET framework, because it's compiled down natively just like other code.
So, the first question we have is: Is the fact that ASPX files are compiled by the runtime hard-coded into the system?
As it turns out, no. ASP.NET has a very flexible dispatching system that can be manipulated via Web.config. If we look into the Machine.config file for the <system.web> settings, we find this interesting section titled <httpHandlers>. Inside this section, you'll find an entry like:
<add type="System.Web.UI.PageHandlerFactory" path="*.aspx" verb="*" />
Our first clue about what happens is here. When the ASP.NET system sees a URL that ends in ".aspx", it goes off and instantiates this PageHandlerFactory class. This guy is what's responsible for compiling the ASPX file into code and injecting it into our AppDomain so that it can be run alongside the rest of our code. The inner guts of PageHandlerFactory are interesting, but something to be tackled for another day.
The important information here is: we can map URL patterns to arbitrary classes, and get our own code called when a request comes in.
What does it take to get the ASP.NET runtime to call your code, instead of look for and compile an ASPX file? Write a handler (or a handler factory). That means implementing IHttpHandler, or IHttpHandlerFactory. A handler factory is really a meta-class that finds the right handler, and then hands it off to the runtime. As you can tell, the PageHandlerFactory is one of those; it finds the ASPX file, compiles it, and then hands off an instance of that new class. Implementing a handler factory is an exercise left for the reader, which should be simple after you understand how to implement a handler.
Implementing a handler is pretty simple:
using System; using System.Web; public class TestHandler : IHttpHandler { bool IHttpHandler.IsReusable { get { return false; } } void IHttpHandler.ProcessRequest(HttpContext ctxt) { ctxt.Response.Write("Hello!"); } }
Now that we have our class written, we just need to tell the ASP.NET runtime when to call it. Like the line we saw in Machine.config, we need to add a line to our Web.config to hook a URL into our class. Assuming our class is in an assembly called TestHandlerAssembly, the Web.config file might look like this:
<configuration> <system.web> <httpHandlers> <add verb="*" path="testhandler.aspx" type="TestHandler, TestHandlerAssembly" /> </httpHandlers> </system.web> </configuration>
Let's assume you mapped this web application under http://localhost/webapp1/. If you issued a request for http://localhost/webapp1/testhandler.aspx, you should get a page that says "Hello!". If you view source on the page, you'll see that it's not even HTML: it's just a single line that says "Hello!".
This should give you an indication of the power and flexibility here: you have complete control over what goes out into the data stream. It certainly doesn't even have to be HTML; it could be, for instance, an RSS feed, or an image, or pretty much anything that might be useful to a web browser for display or download.
The next step to utilizing this method of response creation is to understand server-side controls. For this, I highly recommend the book Developing Microsoft ASP.NET Server Controls and Components by Nikhil Kothari and Vandana Datye. This book will not only give you an excellent foundation for the basics of how server controls work, but some terrific examples of how to write your own.
You might also be interested in my Attribute Based URL Dispatching article.
You can't do these things alone. Thanks to Peter Provost and Scott Watermasysk for being my technical advisors for this article.
About the AuthorBrad Wilson is a .NET technology consultant and a frequent contributor to .NET related mailing lists. When not writing at his web log, he spends much of his time looking for inventive ways to break ASP.NET and bend it to his will. :) Brad lives in beautiful Parker, Colorado. He is an avid game player, including poker, backgammon, cribbage, and Go. If you have any questions or concerns about his articles, you may contact Brad here. |
![]() |