The Cost Of Client-Side Redirects In ASP.NET And Using Page Modules

In an ASP.NET application the instances of the HttpApplication class are responsible for handling the requests. These instances are created by the ASP.NET infrastructure and each one may serve many request in its lifetime, however, serving only one at a time.

An application executes events that are handled by modules or user code that is defined in the Global.asax file in the following sequence:

  1. BeginRequest - Occurs as the first event in the HTTP pipeline chain of execution when ASP.NET responds to a request.

  2. AuthenticateRequest - Occurs when a security module is establishing the identity of the user.

  3. PostAuthenticateRequest - Occurs when a security module has established the identity of the user.

  4. AuthorizeRequest - Occurs when a security module is verifying user authorization.

  5. PostAuthorizeRequest - Occurs when a security module has verified user authorization.

  6. ResolveRequestCache - Occurs when ASP.NET completes an authorization event to let the caching modules serve requests from the cache, bypassing execution of the HTTP handler (for example, a page or an XML Web service).

  7. PostResolveRequestCache - Occurs when ASP.NET acquires the current state (for example, session state) that is associated with the current request.

    After the PostResolveRequestCache event and before the PostMapRequestHandler event, an HTTP handler (usually, a page corresponding to the request URL) is created. This is usually accomplished by instantiating a class that implements the IHttpHandler interface or by requesting one from a class implementing the IHttpHandlerFactory interface.

  8. PostMapRequestHandler - Occurs when ASP.NET has mapped the current request to the appropriate event handler.

  9. AcquireRequestState - Occurs when ASP.NET acquires the current state (for example, session state) that is associated with the current request.

  10. PostAcquireRequestState - Occurs when the request state (for example, session state) that is associated with the current request has been obtained.

  11. PreRequestHandlerExecute - Occurs just before ASP.NET begins executing an event handler (for example, a page or an XML Web service).

    The HTTP handler is executed.

  12. PostRequestHandlerExecute - Occurs when the ASP.NET HTTP handler (for example, a page or an XML Web service) finishes execution.

  13. ReleaseRequestState - Occurs after ASP.NET finishes executing all request event handlers. This event causes state modules to save the current state data.

  14. PostReleaseRequestState - Occurs when ASP.NET has completed executing all request event handlers and the request state data has been stored.

    After the PostReleaseRequestState event, response filters, if any, filter the output.

  15. UpdateRequestCache - Occurs when ASP.NET finishes executing an event handler in order to let caching modules store responses that will be used to serve subsequent requests from the cache.

  16. PostUpdateRequestCache - Occurs when ASP.NET completes updating caching modules and storing responses that are used to serve subsequent requests from the cache.

  17. EndRequest - Occurs as the last event in the HTTP pipeline chain of execution when ASP.NET responds to a request.

Both HTTP Modules and the Global.asax (a class derived from the HttpApplication class) file allow you to subscribe to any of these events, the main difference being that there can only be one Global.asax file per application but as many HTTP modules as need.

If you need to do something with your HTTP handlers you can get a the instance handling the request from the Handler property of the HTTP Context and subscribe to any events that that HTTP handler might have (like if it's a Page, for example).

Problems arrive when in the execution of the HTTP handler a call is made to Server.Transfer method. The execution of the HTTP handler you were controlling stops executing and execution transfers to a new HTTP handler which neither Global.asax or any HTTP Module has any way to being notified of its existence.

If you really need to control that HTTP handler, you start calling the Response.Redirect instead of the Server.Transfer method. When you do this, you'll have to go through the whole ASP.NET Application Life Cycle with all the costs associated. These costs can be considerable and not obvious to the inexperienced:

  • Network Costs
    • Bandwidth occupation - Besides the occupation of the connection, the number and size of cookies can get large (Session, Authentication, Roles).
    • Network Latency - Traveling through the network takes time.
    • If Windows authentication is being used, a negotiation with the client is needed.
  • Server Costs (Otherwise unnecessary processing)
    • Saving and loading session state, if using a database for storage, takes time and introduces contention on the database and other requests for the same session.
    • If Windows authentication is being used, a negotiation with the client is needed.
    • Authorization will need to go through the list of file and URL authorizations and might need to use an authorization provider.
    • Handle events for undesired HTTP handlers (like web resources and script resources, for example).

Using Page Modules, you only need to go through the the ASP.NET Page Life Cycle for pages while being able to control all of them when using Server.Transfer.

Published Wednesday, September 12, 2007 1:26 AM by Paulo Morgado

Leave a Comment

(required) 
(required) 
(optional)
(required)