Browse DevX
Sign up for e-mail newsletters from DevX


A Low-level Look at ASP.NET Architecture : Page 5

Many developers are familiar only with the high-level .NET frameworks like Web Forms and Web services that sit at the very top level of the ASP.NET hierarchy. This article discusses the lower-level aspects of ASP.NET and explains how requests move from Web Server to the ASP.NET runtime and then through the ASP.NET HTTP pipeline to process requests.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

Flowing through the ASP.NET Pipeline
The HttpApplication manages request flow by firing events that signal your application that things are happening. This occurs as part of the HttpApplication.Init() method (look at System.Web.HttpApplication.InitInternal and HttpApplication.ResumeSteps() with Reflector), which sets up and starts a series of events in succession, including the call to execute any handlers. The event handlers map to the events that are automatically set up in global.asax, and they also map any attached HttpModules, which are essentially an externalized event sink for the events that HttpApplication publishes.

Both HttpModules and HttpHandlers are loaded dynamically via entries in web.config and attached to the event chain. HttpModules are actual event handlers that hook specific HttpApplication events, while HttpHandlers are an end point that gets called to handle "application-level request processing."

Figure 6. HTTP Pipeline Event Flow: The HttpApplication object's events drive requests through the pipeline. Http modules can intercept these events and override or enhance existing functionality.
Both modules and handlers are loaded and attached to the call chain as part of the HttpApplication.Init() method call. Figure 6 shows the various events, when they happen, and which parts of the pipeline they affect.

HttpContext, HttpModules, and HttpHandlers
The HttpApplication itself knows nothing about the data being sent to the application—it is a merely messaging object that communicates via events. It fires events and passes information via the HttpContext object to the called methods. The actual state data for the current request is maintained in the HttpContext object mentioned earlier. It provides all the request-specific data and follows each request from beginning to end through the pipeline. Figure 7 shows the flow through ASP.NET pipeline. Notice the Context object, which is your compadre throughout the request and can be used to store information in one event method and retrieve it in a later event method.

In Figure 7, the Application acts as the hosting container that loads up the Web application and fires events as requests come in and pass through the pipeline. Each request follows a common path through the HTTP filters and modules configured. Filters can examine each request going through the pipeline and handlers allow implementation of application logic or application level interfaces such as Web Forms and Web services. To provide input and output for the application, the Context object provides request-specific information throughout the entire process.

Figure 7: ASP.NET Request Pipeline: The figure shows requests flowing through a set of event interfaces.
After the pipeline is started, HttpApplication starts firing events one by one as shown in Figure 6. Each of the event handlers is fired and any events are hooked up to those handlers execute and perform their tasks. The main purpose of this process is to eventually call the HttpHandler hooked up to a specific request. Handlers are the core processing mechanism for ASP.NET requests and are usually the place where any application level code is executed. Remember that the ASP.NET page and Web service frameworks are implemented as HttpHandlers—and that's where all the core processing of the request is handled. Modules tend to be of a more core nature used to prepare or post process the context that is delivered to the handler. Typical default handlers in ASP.NET are Authentication, Caching for pre-processing, and various encoding mechanisms on post processing.

There's plenty of information available on HttpHandlers and HttpModules so to keep this article a reasonable length I'm going to provide only a brief overview of handlers.

As requests move through the pipeline a number of events fire on the HttpApplication object. You've already seen that these events are published as event methods in Global.asax. This approach is application-specific though, which is not always what you want. If you want to build generic HttpApplication event hooks that can be plugged into any Web application, you can use HttpModules, which are reusable and require no application specific code except for an entry in web.config.

Modules are in essence filters—similar in functionality to ISAPI filters at the ASP.NET request level. Modules allow hooking events for EVERY request that pass through the ASP.NET HttpApplication object. These modules are stored as classes in external assemblies that are configured in web.config and loaded when the application starts. By implementing specific interfaces and methods the module then gets hooked up to the HttpApplication event chain. Multiple HttpModules can hook the same event; event ordering is determined by the order they are declared in web.config. Here's what a handler definition looks like in web.config:

<configuration> <system.web> <httpModules> <add name= "BasicAuthModule" type="HttpHandlers.BasicAuth,WebStore" /> </httpModules> </system.web> </configuration>

Note that you need to specify a full type name and an assembly name without the DLL extension.

Modules let you look at each incoming Web request and perform an action based on the events that fire. Modules are great for modifying request or response content, providing custom authentication, or otherwise providing pre-or-post-processing to every ASP.NET request in a particular application. Many of ASP.NET's features such as the authentication and session engines are implemented as HTTP modules.

While HttpModules feel similar to ISAPI filters in that they look at every request that comes through an ASP.NET application, they are limited to looking at requests mapped to a single specific ASP.NET application or virtual directory—and only to requests that are mapped to ASP.NET. Thus you can look at all ASPX pages or any of the other custom extensions that are mapped to this application. You cannot, however, look at standard .HTM or image files unless you explicitly map the extension to the ASP.NET ISAPI DLL by adding an extension as shown in Figure 1. A common use for a module might be to filter requests for JPG images in a special folder, displaying a "SAMPLE" text overlay on top of every image by drawing on top of the returned bitmap with GDI+.

Implementing an HTTP module is very easy: You must implement the IHttpModule interface, which contains only two methods: Init() and Dispose(). The event parameters passed include a reference to the HTTPApplication object, which in turn gives you access to the HttpContext object. In these methods you hook up to HttpApplication events. For example, if you want to hook the AuthenticateRequest event with a module you would do what's shown in Listing 5.

Remember that your module has access to the HttpContext object and from there to all the other intrinsic ASP.NET pipeline objects such as Response and Request, so you can retrieve input, etc. But keep in mind that certain things may not be available until later in the chain.

You can hook multiple events in the Init() method so your module can manage multiple functionally different operations in one module. However, it's probably cleaner to separate differing logic out into separate classes to make sure the module is modular. In many cases functionality that you implement may require that you hook multiple events—for example, a logging filter might log the start time of a request in BeginRequest and then write the request completion into the log in EndRequest.

Watch out for one important gotcha with HttpModules and HttpApplication events: Response.End() or HttpApplication.CompleteRequest() will shortcut the HttpApplication and mModule event chain (see Sidebar 2).

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date