I ran across a situation yesterday where ASP.Net web.config inheritance bit me in a way that wasn’t pleasurable. Here is my situation.
I have 2 ASP.Net web applications on a single IIS web site, 1 ASP.Net web app and 1 WCF web services. For example:
| IIS Setting | Virtual Path | Comments |
| www.MyWepApp.com | \MyWebApp | This is my 2.0 ASP.Net web application |
| www.MyWebApp.Com\MyServices\ | \MyWebApp\MyServices | This is my 3.5 WCF web services |
As you can see, I have a hierarchy going on where “MyServices” is an IIS web application under the IIS web site (also an IIS web app) “MyWebApp” and “MyServices” is a sub-directory under “MyWebApp.” Since we have a web application at the IIS web site root (“MyWebApp”) and that site has a web.config, ASP.Net inheritance kicks in for any web applications that are “children” to “MyWebApp.”
So the error message I was getting was that I already had a <sectionGroup> defined for “System.Web.WebExtensions" when I tried to invoke a web service under “MyServices.” Sure enough, If I looked at both web.config’s the <configSections> were duplicated. After some searching I found you can do two things to avoid these conflicts. (1) Make sure the <confiSections> point to the same assembly versions and (2) add a <location> element to your root web.config and set it to not allow child inheritance.
So let’s look at (1) – Making sure the <configSections> match. Here is the config section from the web app:
<configSections>
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" allowDefinition="Everywhere"/>
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" allowDefinition="MachineToApplication"/>
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" allowDefinition="MachineToApplication"/>
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
Here is the section from my web services:
<configSections>
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
Notice the differences in the Version numbers of the assemblies. The Web app had references to the 1.0 assemblies and the web services had references to the 3.5 assemblies. Because of ASP.Net inheritance, whenever I tried to consume a web service it tried to “re-write” the same config sections because they have the same name but different values. Updating the <configSection> of the web app to match the web services (all pointing to the 3.5 assemblies allowed me to work. This is because the <configSections> that have the same name in both web.configs now have the same value.
For (2) adding the <location> element to the root web.config here is the line I added:
</configSections>
<location inheritInChildApplications="false">
<system.web>
There are a couple of things to note here. (1) the <location> element must be after the <configSections> and before the <system.web> If you have <appSettings> or any thing else those must also be outside the <location> element.
(2) the “inheritInChildApplications” attribute is not defined in the asp.net web.config schema which is why it has a red underline. That is ok. Apparently Microsoft added this to the asp.net engine but not to the schema. Whatever it works.
(3) because of note (1) and the fact that <location> wraps the <system.web> section, all other sections are using asp.net inheritance, which is why we have to deal with (1) and the same version of the <sectionGroups> assemblies anyhow.