I am sure like me
you have found the use of HTTPModules in ASP.NET very useful in overcoming
certain challenges. HTTPModules allow you to intercept requests and perform some
process on the request. One example would be to write an HTTPModule that
restricts access to an application by IP address.
Using HTTPModules unders one website with multiple applications (virtual
directories) can be confusing. This article will briefly explain one possible solution to using
HTTPModules in a multiple application environment.
Configuration files in ASP.Net applications are hierarchical. Configuration
settings propagate from the root folder to all sub folders within the
application. This is known as Configuration Inhertiance. However, If a configuration file exists within one of the application's
sub-directory, its settings will overwrite that of the root configuration.
So, what is the top of the pyramid?
Well it is an often forgotten configuration file called the machine.config file.
This file is located in the
%windir%\Microsoft.NET\Framework\Version\CONFIG directory. This is akin
to the master control ro configuration file. The settings here affect all ASP.Net applications
running on the web server. That's pretty powerful stuff when you stop to think
about it.
Next, are the building blocks. The block of our pyramid are the applications
running on the web server. Each application inherits its initial settings from the
machine.config. Now how do we set configuration for the current application you
ask? That is the web.config file. The web.config file can exist for every
application. This file has many settings that are available. Each setting is
part of various configuration sections in these configuration files.
One section in the web.config concerning this is the httpModules section. This
section is where the HTTPModules are registered for the application.
<configuration>
<system.web>
<httpmodules>
<add type="System.Web.State.CacheModule" name="OutputCache" />
<add type="System.Web.State.SessionStateModule" name="Session" />
</httpmodules>
</system.web>
</configuration>
So it's easy enough to add the HTTPModule. Now why when I run another
application does it try to load the HTTPModule even though the application
web.config file does not add it? Let's take the following example application /
virtual directory structure.
MainApp1/
SubApp1/
SubApp2/
SubApp3/
So MainApp1 is our root level application. Easy enough. This is like installing
your application in the root of a website. Now let's say that we use an
HTTPModule in the MainApp1 application and configure it in our web.config file
as follows.
<configuration>
<system.web>
<httpmodules>
<add name="HTTPModule" type="DotNetNuke.HTTPModule, DotNetNuke" />
</httpmodules>
</system.web>
</configuration>
Ok, so now our application has registered and can use this HTTPModule. Now on to
SubApp1. This is a complete different application setup as a new application in
the IIS administration console. It has it's own web.config file that does not
even contain a single
</httpmodules> section. Unfortunately, when we run the application we get an error from
ASP.Net stating that the HTTPHandle DotNetNuke could not be loaded as the .dll
file could not be found.
Let me explain. What has happened is that IIS has handed your request for SubApp1
off to the Aspnet_isapi.dll. This is the .dll that handles all ASP.Net requests
in IIS. Now remember our hierarchy; ASP.Net loads the configuration first from
the Machine.config file. Then the application directory structure is traversed.
The MainApp1 web.config file is found, read and used. Hmmmm....that loaded the
HTTPModule declaration. Finally the web.config file for our SubApp1 application
is read. As you may be able to see by now, the HTTPModule was loaded from the
MainApp1 web.config and is still in place when SubApp1 runs.
So how do we fix this? It's easy. Remember that settings are inherited unless
explicitly changed. Now it is time for us to explicitly change them for our
application. Not only can we add httpModules in the web.config file, but we can
also remove individual ones or even clear them all. That is what we are going to
do, by adding the following to our web.config file for SubApp1 we are clearing
all HTTPModules explicitly.
<configuration>
<system.web>
<httpmodules>
<clear />
</httpmodules>
</system.web>
</configuration>
That is all there is to it. Our SubApp1 runs fine now.
One more quick note. Instead of using clear as I've done above, it may be better to use the </Remove> element instead.
This applies in cases where you want to inherit a module from the root configuration or the server's machine configuration file.
An example is show below
<configuration>
<system.web>
<httpmodules>
<remove name="HttpModule" />
</httpmodules>
</system.web>
</configuration>
But what do you do when there are many settings in your root web.config file that
you don't want to be propagated to your child applications?