ASP.NET files and inheritance
I've been completely silent on my blog for a few months while having my head down in projects, but I thought I should start up some activity, even if it's a quickie. I feel that I've been covering so much ground but not enough time to report on it.
I was asked today about ASP.NET web.config inheritance. Understanding which ASP.NET files and folders are inherited through folders and applications makes development and troubleshooting so much easier.
Here is the summary to keep in mind:
- web.config files inherit all the way down the tree, past all application boundaries.
- global.asax only lives within its application
- /bin and the /app_{folders} only live within their application
So, this means that anything set in the root web.config file will inherit down the entire site, even if some folders are marked as applications.
Where this gets messy is if the web.config file has references to assemblies but sub-applications don't have those assemblies. For example, let's say that you have a HTTP Module configured in the root of the site and referenced from the site web.config file. If you have a sub-application called /subfolder which is marked as an application, then /subfolder will attempt to load the HTTP Handler from /subfolder/bin. Since it doesn't exist, an error will be thrown.
There are multiple ways around this. Probably the cleanest if the HTTP Handler isn't needed in /subfolder is by 'removing' the reference by adding a <remove> clause in the /subfolder/web.config file. You can do this with <remove name="name" />. Here is an example of how to remove a HTTP Module in a subfolder:
<httpModules>
<remove name="ErrorLog"/>
</httpModules>
Here is what the site web.config might look like:
<httpModules>
<add name="ErrorLog" type="GotDotNet.Elmah.ErrorLogModule, GotDotNet.Elmah, Version=1.0.5527.0, Culture=neutral, PublicKeyToken=978d5e1bd64b33e5" />
</httpModules>
A property on the other hand will need to be set to nothing. For example, let's say that your site web.config file has <pages styleSheetTheme="SiteTheme" /> set.
That setting will carry all the way down the site, past all application barriers. But, let's say that a sub-application doesn't have the App_Theme set, an error will be thrown in the sub-application. One solution is to add the following to the sub-application's web.config file.
<pages styleSheetTheme="" />
As I mentioned above, there are multiple solutions. Another solution is to put a copy of the assembly or App_Theme folder in the sub-applications. Yet another option as a last resolve is to put a skeleton assembly just to keep the web.config settings happy. There should be little reason to resort to this though.
For the themes and other properties of that nature, you can usually override them either implicitly or explicitly from the page or code-behind.
Another situation to keep in mind is if you set some folders that use ASP.NET v1.x and others that use ASP.NET v2.x. The site web.config will be used by both frameworks. With this in mind, make sure that you don't have something in one web.config file that isn't compatible with other framework versions further down the same site path. For example, setting the <connectionStrings> section of web.config will cause an error with v1.x of the framework. Of course this only happens in the rare situation that you have ASP.NET v2.x in place with v1.x in a subfolder. For example, if you have v1.x used for legacy testing, or to support part of the site that doesn't run on v2.x for some reason, then you may have this configuration
That's all there is to it. Make sure to remember that web.config inherits all the way down the site tree but none of the other .NET files do and you'll be a step further in easier and more powerful development and troubleshooting.