ASP.NET Web Forms Extensibility: Modules
Next in the series is modules. So, what is a module, and what does it do?
A module is some class that implements IHttpModule. This is a very simple interface, which only defines two methods:
- Init: this is the “body” of the module, where you place it’s logic (more on this later), called when the application is started (typically, upon the first request, unless you are doing application initialization);
- Dispose: called when the application shuts down.
A module is typically statically registered on the Web.config file, although I have talked in the past on how to register modules dynamically. While a module usually does not actually do anything by itself, it is useful for registering event handlers for ASP.NET application lifetime events, such as Error, BeginRequest, EndRequest and their likes. Please note that there is no event for the Start occurrence (normally handled on the custom Global class on an Application_Start method), you can just use the Init method for that, since it is called upon application startup.
Out of the box ASP.NET includes a number of modules, which you can find on the global Web.config file, located in %WINDIR%\Microsoft.NET\Framework64\v4.0.30319\Config, some of which you are free to disable, that is, remove on you local Web.config file:
1: <!-- for IIS < 7 -->
2: <httpModules>
3: <remove name="PassportAuthentication" />
4: </httpModules>
5: <!-- for IIS 7+ -->
6: <system.webServer>
7: <modules>
8: <remove name="PassportAuthentication" />
9: </modules>
10: </system.webServer>
11:
As you can see from the above snippet, one such module is PassportAuthentication, implemented by PassportAuthenticationModule, one that is marked as deprecated in current versions of .NET. Now, there are two sections where modules can be registered, one for IIS versions prior to 7, and the other for recent versions. Of course, if you only use one of them, do forget about the other section.
A simple module implementation would be:
1: public class FooterModule : IHttpModule
2: {
3: void IHttpModule.Init(HttpApplication context)
4: {
5: context.EndRequest += (sender, e)
6: {
7: HttpContext.Current.Response.Write(String.Format("<p>Generated at {0}</p>", DateTime.UtcNow));
8: };
9: }
10:
11: void IHttpModule.Dispose()
12: {
13: }
14: }
This module registers an event handler for the EndRequest event, which, when called, outputs a string to the response. Nothing to be done on disposing, in this case, but a typical use case would be to release any sort of “heavy” module-held resources when the application shuts down. Please be careful to perform operations only when you can, for example, session is only available after the AcquireRequestState event is raised (and, of course, only for handlers implementing IRequiresSessionState), caller identity is only set after the AuthenticateRequest and authorization is only confirmed after AuthorizeRequest.
You should favor writing code that handles an event in a module as opposed to having a similar method on Global.asax.cs because a module is more portable – you can even reuse it between different assemblies.
Once you are finished, you need to register your module on Web.config, to have it being set up automatically. You have to give it a unique name and add an entry like the following:
1: <!-- for IIS < 7 -->
2: <system.web>
3: <httpModules>
4: <add name="MyModule" type="MyNamespace.MyModule, MyAssembly"/>
5: </httpModules>
6: </system.web>
7: <!-- for IIS 7+ -->
8: <system.webServer>
9: <modules runAllManagedModulesForAllRequests="true">
10: <add name="MyModule" type="MyNamespace.MyModule, MyAssembly"/>
11: </modules>
12: </system.webServer>
Next, handlers and routes!