This article explains how to implement a sub application such as a blog in your website without experiencing dependency issues. A common problem that developers experience is when their sub applications accidentally inherit requirements of the parent website. This is actually by design but read on if this is causing problems in your site.
This problem has caught me out a couple of times so far but usually with enough of a gap between occurrences that it had become just a fuzzy memory. Hopefully by writing this article it will solidify it in my head and also help out other developers experiencing this for the first time.
Unfortunately this problem doesn't have a specific phrase or keyword that will make it easy for developers to find this solution in search engines. I want to rephrase this a couple of ways to hopefully capture the terms a developer might use when trying to solve this problem:
- My blog, forum, gallery is requiring dlls from my parent website
- When I install [software] in my site it tries to load assemblies from the main website
- How do I stop my sub websites from needing the main sites bin folder
- Could not load file or assembly 'assembly name' or one of its dependencies. The system cannot find the file specified.
That should do it but any further phrasings (such as the search term you arrived here through) are welcome in the comments section.
The problem occurs when you install a third party application as an application within an existing web site. I have had this occur when I have done the installation manually and also when I have used the Web PI.
This could encompass any of the applications out there such as forums, blogs, galleries, shopping carts or anything that runs as its own application.
The actual error message will most likely take the format of:
"Could not load file or assembly 'assembly name' or one of its dependencies. The system cannot find the file specified."
The reason this is occurring is actually by design. The settings inside the main web.config will cascade downwards and all other config files will inherit the settings. If they have settings of their own they will override the parent. In fact even the root web.config is being merged with a server wide file called machine.config.
So what's happening is the references to the assemblies in your main \bin\ folder are being passed down to the sub application and when it looks in its own bin folder it finds they aren't their and throws an error.
The obvious solution is to block these settings being inherited by a lower config file. This is achieved by wrapping the <system.web> section in the following tag:
<location path="." inheritInChildApplications="false"> <system.web> <!-- ... --> </system.web> </location>
If you have used DOS or FTP then you will probably realise that in the path="." the dot means current folder. This applies the inheritChildApplications="false" to all applications below the current folder. If you have a virtual folder setup in IIS that is at different physical location this is still counted as below the current application if its virtual url is below the current one.
Running IIS7 or above?
The newer versions of IIS have moved their configuration settings to a new section. If you have a web.config that is for IIS7 then you will need to also wrap <system.webServer> which is further down.
<location path="." inheritInChildApplications="false"> <system.webServer> <!-- ... --> </system.webServer> </location>
You can have more than one <location> block in a web.config so it would be fine to do this to wrap around both sections.
IIS7 and validateIntegratedModeConfiguration
If you were previously relying on the <validation validateIntegratedModeConfiguration="false" /> tag for the correct functioning of your site you might need to follow this technique to avoid a 502.22 Internal Server Error.
Only available in 2.0
Please note that if you're working with an asp.net 1.1 application you will not be able to put this tag in to block child applications as it was only introduced in 2.0. In this case your only real option as far as I know is to add <remove> elements into the child applications to cancel out each of the assemblies loaded in the asp.net 1.1 app. This is not a pretty solution because it tightly couples the two projects together however if you are in this situation and cannot upgrade the 1.1 app to 2.0 then it might be your only way out.
Restrictions with this technique
Please note that you cannot simply wrap the ENTIRE web.config in this tag as the root node must be the <configuration> tag.
There are also certain sections you cannot wrap the <location> tag around such as the <configSections> tag.
You can use more than one <location> tag to exclude various sections. Alternatively you can reorder portions of the web.config so that a single <location> can span multiple sections.
Incompatibilities with the WSAT
If you use the Web Site Administration Tool to configure your directory security you may have problems with the web.configs that the tool places in subdirectories. If this is the case then you can move the contents of the lower web.configs up into the main config and wrap them in a <location path="path to file or folder"> tag.
Breaks local debugging
I have noticed that while this works great for allowing an application and a sub application to work in harmony on the server it can cause confusion when you try to use it on your local dev server. In doing research into this issue it turns out that this is a known bug which has been in the official to do list for quite a while but as it doesn't affect many users hasn't been resolved yet. You can read about and vote for this bug on Microsoft Connect at:
The scenario is that if you place a <compilation debug="true"> element within a <location path="." inheritInChildApplications="false"> element the debug="true" will not be understood.
This means that when you press the play button to start debugging it will compile, launch the site and then immediately close the debug session. Your website will load up and you will be able to use it as normal but if you look at it in visual studio you will see the debug play button is available and the app is not considered to be currently being debugged.
It may also mean that your app will simply fail to compile locally (but works fine on the server).
There is a work around for this; by commenting the <location> element out and restarting the debug process local debugging will being working correctly again.
As of the current version there is no way to automate setting this tag between local and production environments although it may be possible with the new web.config transformations in the upcoming .net 4 release.