The ASP.NET pipeline allows HTTP modules to plug in into the request processing lifecycle and do work at various stages. For example, output caching, authentication, authorization etc. are all implemented as HTTP modules.
However one of the problems is that HTTP modules must be registered in configuration. This is a little painful for writing framework components where an HTTP module is essentially an implementation detail. You don't want every app developer using your framework to have to add in some configuration entries. What you want is the ability to programmatically add HTTP modules to the pipeline. This isn't available out-of-the-box today.
I faced this problem in my previous post around RIA Services, Authentication and Roles, as I needed to handle the PostAuthenticateRequest event. This seems to have come up before (for example here and here on stack overflow).
So in the interim, we can use the new, and somewhat obscure, ASP.NET 4.0 feature, the PreApplicationStartMethodAttribute, that lets you declare some code you want to run early in the initialization phase of your web application, even before any dynamic compilation happens and before any application startup code runs. Combine that capability with an HttpApplication that supports registering HTTP modules programmatically, as we're in business. I wrote DynamicHttpApplication that provides this API (link to code below):
public abstract class DynamicHttpApplication : HttpApplication {
public static void RegisterModule(Func<HttpApplication, IHttpModule> moduleFactory);
}
You'll need to use this class as your base class in Global.asax.cs in your web app instead of the default which is HttpApplication.
With this in place, I can add a class library as a reference, or place it in the bin directory and programmatically register HTTP modules without requiring additional configuration. For example, say I have a user tracking HTTP module that does something interesting with the authenticated user. Here's the code I can write:
[assembly: PreApplicationStartMethod(typeof(UserTrackerModule), "Register")]
namespace DynamicWebApp.Sample {
public sealed class UserTrackerModule : IHttpModule {
#region Implementation of IHttpModule
void IHttpModule.Dispose() {
}
void IHttpModule.Init(HttpApplication application) {
application.PostAuthenticateRequest += delegate(object sender, EventArgs e) {
IPrincipal user = application.Context.User;
if (user.Identity.IsAuthenticated) {
DateTime activityDate = DateTime.UtcNow;
// TODO: Use user.Identity and activityDate to do
// some interesting tracking
}
};
}
#endregion
public static void Register() {
DynamicHttpApplication.RegisterModule(delegate(HttpApplication app) {
return new UserTrackerModule();
});
}
}
}
Basically it is a normal/typical IHttpModule implementation that you might write with one thing extra: a static Register method that is declared to be the PreApplicationStartMethod in the assembly's metadata.
HTTP modules provide powerful ways to do interesting things in ASP.NET. For example, we do some pretty creative things in RIA Services with our HTTP module. The ASP.NET infrastructure lets framework components do their job, and now they can do so without needing ugly configuration entries.
Links
Source code containing the DynamicHttpApplication (its fairly simple ... implemented in around ~50 lines of code) that you can use in your own app, along with the sample above.
Posted on Thursday, 7/1/2010 @ 7:29 AM
| #
ASP.NET