Sunday, November 21, 2010

Write custom ASP.NET HTTP Handler with IronPython

An HTTP handler is the endpoint that responds to handle request made by an ASP.NET Web application. The request is mapped to HTTP handler based on name pattern (commonly file extension). ASP.NET provides a few default HTTP handlers: Page handler (.aspx), Web Service handler (.asmx), Generic handler (.ashx) and so forth.

ASHX Generic handler is special since it allows to implement IHttpHandler API immediately.
There is a sample - HelloWorld.ashx:

Language attribute allows me to chose program language to use, but it strongly limited by only two - C# and VB. What if I want to write my code in Python?

.NET actually provides support for Python language with IronPython. And I assume that it is possible to write such a handle using IronPython. But How?

.ashx is mapped to System.Web.UI.SimpleHandlerFactory. When .ashx file is requested, this handler parses .ashx file into .NET class and compiles it using either C# or VB compiler (accordingly to language attribute). Using another language requires to setup suitable compiler for this language, handle parsing and so on. I am not sure I want to work so hard for that.

So I chose an alternative way. I will create my own handler, which will process a python code.

At first I chose a file extension to be mapped - .pyhx.
I want .pyhx be pure python code but looks similar to .ashx. Each file will define a class implements IHttpHandler. The name of the class have to be the same as the file name.
There is a sample - HelloWorld.pyhx:

The next step is implementing IHttpHandlerFactory, to which .pyhx will be mapped.
Such factory creates instances of IHttpHandler defined in .pyhx (pure Python code). It works similar to SimpleHandlerFactory, but instead of parsing and compiling the file, it executes the python code using advantage of DLR hosting API.

There is C# implementation:

The only thing is left is to declare .pyhx mapping in Web.config:

That's it! You can write your custom HTTP handler in Python as well as in C# and VB!

The sample project may be found on GitHub: