Disable web.config Inheritance and Using HTTPModules in a Multiple Application Environment

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?

Here is the solution:
With the <location> attribute with inheritInChildApplications set to false in your root web.config file you can restrict configuration inheritance.
So, by wrapping a section of your web.config file in <location> attribute you can instruct ASP.NET not to inherit those settings to child applications/folders and their web.config files.

In fact  you can wrap the whole <system.web> section in one <location> attribute and disable configuration inheritance so none of the parent settings from <system.web> will be inherited to the child applications you create in subfolders.

Here is how to use this in practice:
     <location
            path="." inheritInChildApplications="false">
                <system.web>
			...
                </system.web>
  </location>
NOTE: Do remember that if you do this, you need to manually insert all the settings you need in the <system.web> for your child applications because none of the settings from the root web.config will be propagated...

Published Tuesday, 02 Sep. 2008. 00:09

COMMENTS

 
Mon, 06 Dec. 2010. 12:12 by Abdul Muheet

Awesome article... Keep writing........

Tue, 24 May. 2011. 22:05 by Maria Limon

Thanks so much. This fixed my problem.

Thu, 17 Nov. 2011. 12:11 by Lewis

What if I *do* want to run a module in the child application, using a type contained within the parent applications's assembly. Is there a way to do that?

Thu, 17 Nov. 2011. 13:11 by Gerald Nupa


What if I *do* want to run a module in the child application, using a type contained within the parent applications's assembly. Is there a way to do that?


Please refer to the post where I talk about using the remove attribute instead of the clear attribute.
the remove attribute prevents propagation of individual httpModules down to sub applications.

If however you are asking about using an httpModule type defined within the parent application's assembly within the child application then provided the sub-application is defined as a "Web Application" within IIS , then you will have to add a reference to the parent assembly in your child assembly.

Have you tried any of the above suggestions and it did not work?

Tue, 19 Nov. 2013. 10:11 by Hello

Hello

Tue, 19 Nov. 2013. 10:11 by Hello

Hi,

If I have multiple entries in the config file for the sections, what is the order of execution of the same? I have a scenario where-in, after executing the first 3 Modules, the call goes back to the first module rather than 4th Module.

 

Leave a Comment

Your Name (required):
Your Comment (required):
67.29.2
Please enter the code above in the box below without the dots:
Other Great Blogs
Bimeyen's Blog
Ndikum's Blog
Check this great idea on how to Send Great gifts to family in Cameroon. Click below. Lost of people talking about it and using it too...

SEARCH

GO

ARCHIVES