Programming Microsoft ASP.NET 4 - Dino Esposito [79]
In the end, building asynchronous handlers is definitely tricky and not for novice developers. Very likely, you are more interested in having asynchronous pages than in generic asynchronous HTTP handlers. With asynchronous pages, the “lengthy task” is merely the ProcessRequest method of the Page class. (Obviously, you configure the page to execute asynchronously only if the page contains code that starts I/O-bound and potentially lengthy operations.)
ASP.NET offers ad hoc support for building asynchronous pages more easily and more comfortably than through HTTP handlers.
Caution
I’ve seen several ASP.NET developers use an .aspx page to serve markup other than HTML markup. This is not a good idea. An .aspx resource is served by quite a rich and sophisticated HTTP handler—the System.Web.UI.Page class. The ProcessRequest method of this class entirely provides for the page life cycle as we know it—Init, Load, and PreRender events, as well as rendering stage, view state, and postback management. Nothing of the kind is really required if you only need to retrieve and return, say, the bytes of an image. HTTP handlers are an excellent way to speed up particular requests. HTTP handlers are also a quick way to serve AJAX requests without writing (and spinning up) the whole machinery of Windows Communication Foundation (WCF) services. At the very end of the day, an HTTP handler is an endpoint and can be used to serve data to AJAX requests. In this regard, the difference between an HTTP handler and a WCF service is that the HTTP handler doesn’t have a free serialization engine for input and output values.
Writing HTTP Modules
So you’ve learned that any incoming requests for ASP.NET resources are handed over to the worker process for the actual processing. The worker process is distinct from the Web server executable so that even if one ASP.NET application crashes, it doesn’t bring down the whole server.
On the way to the final HTTP handler, the request passes through a pipeline of special runtime modules—HTTP modules. An HTTP module is a .NET Framework class that implements the IHttpModule interface. The HTTP modules that filter the raw data within the request are configured on a per-application basis within the web.config file. All ASP.NET applications, though, inherit a bunch of system HTTP modules configured in the global web.config file. Applications hosted under IIS 7.x integrated mode can configure HTTP modules that run at the IIS level for any requests that comes in, not just for ASP.NET-related resources.
An HTTP module can pre-process and post-process a request, and it intercepts and handles system events as well as events raised by other modules.
The IHttpModule Interface
The IHttpModule interface defines only two methods: Init and Dispose. The Init method initializes a module and prepares it to handle requests. At this time, you subscribe to receive notifications for the events of interest. The Dispose method disposes of the resources (all but memory!) used by the module. Typical tasks you perform within the Dispose method are closing database connections or file handles.
The IHttpModule methods have the following signatures:
void Init(HttpApplication app);
void Dispose();
The Init method receives a reference to the HttpApplication object that is serving the request. You can use this reference to wire up to system events. The HttpApplication object also features a property named Context that provides access to the intrinsic properties of the ASP.NET application. In this way, you gain access to Response, Request, Session, and the like.
Table 4-7 lists the events