Wednesday, 7 April 2010

SOLVED: IIS7, validateIntegratedModeConfiguration and inheritInChildApplications clash

This article covers an edge case you might have encountered when using the inheritInChildApplications attribute with a web site hosted on IIS7 and provides two possible solutions to your problem.

Scenario

You are trying to set up a sub application in your website and you wrap the <location path="." inheritInChildApplications="false"> element around your <system.webServer> element to break dependencies between apps.

Despite having followed the correct instructions you still see an error message the next time you try to load the parent site. The error looks something like this:

HTTP Error 500.22 - Internal Server Error
An ASP.NET setting has been detected that does not apply in Integrated managed pipeline mode.

This error occurs when you end up with the following configuration elements:

<configuration>
  <system.web>
    <!-- ... -->
    <httpModules>
      <!-- ... -->
    </httpModules>
    <httpHandlers>
      <!-- ... -->
    </httpHandlers>
  </system.web>
  <!-- ... -->
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <validation validateIntegratedModeConfiguration="false" />
      <!-- ... -->
    </system.webServer>
  </location>
  <!-- ... -->
</configuration>

The important part here is that you have wrapped your <system.webServer> in a <location> tag to prevent inheritance. If that <system.webServer> tag contained a <validation> tag and there are still <httpModules> or <httpHandlers> further up the web.config then your validateIntegratedModeConfiguration attribute is going to cause this error.

What is validateIntegratedModeConfiguration?

The official documentation is here:

It is a simple housekeeping mechanism which stops you from accidentally using the old IIS6 httpHandler / httpModule registration mechanism in IIS7.

In the old IIS6 days you would have registered these elements under the <system.web> tag as described in the snippet above. IIS7 registers these under the <system.webServer> tag.

The reason that you would have put this <validate> tag into your web.config in the first place is because like many developers you are using Cassini. This is the dev server built in to Visual Studio and its based off IIS6.

This means that if your site is hosted on IIS7 you need both sets of tags and adding the <validation> snippet allowed this scenario without throwing the error.

The reason that its now showing up is that the <location> snippet does some funny things to the visibility of tags. It basically hides the <validation> setting from view and then complains because it has found both sets of registration tags.

Luckily there are two simple solutions to this problem.

Solution 1: remove the old registration mechanisms

If the scenario fits for you now then the simples solution is to simply remove the <httpHandler> and <httpModule> tags from <system.web>. This would mean that you have since changed over from using Cassini to using a local installation of IIS7. If you have then you no longer need the old tags and you can remove them.

However, its likely that you haven't changed over to this development setup and what you really need is to keep both sets of tags and still be able to stop inheritance with the <location> tag.

Solution 2: move the validation tag outside of the location tag

Something I discovered when tackling this problem was that the web.config was happy to have more than one <system.webServer> inside a single .config file.

This means that you can simply move the <validation> tag outside of the <location> tag and put it inside a second <system.webServer> tag that's visible to all.

This means that the setting will be inherited into sub applications but for my purposes this was not a problem.

Following this technique you would end up with a web.config that had an outline roughly like the following:

<configuration>
  <system.web>
    <!-- keep httpModules and httpHandlers tags in here -->
  </system.web>
  <system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
  </system.webServer>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <!-- your original system.webServer tags stay in here -->
    </system.webServer>
  </location>
</configuration>

As you can see there are now two <system.webServer> tags in the snippet and the second one has the <location> tag wrapped around it. In a real situation you would probably want to wrap the <system.web> tag in a <location> as well - or just wrap the two in one big <location> and move your new <system.webServer> outside of it.

Impersonation

One parting note is that if you read the official MSDN documentation that I link to above you will see there is actually a third tag that will trigger the validation error:

<identity impersonate="true" />

I didn't include this in the article because I have never used it and I didn't want to give out bad advice. If my solutions above don't solve your problems then perhaps checking if you are using this third tag might help!

8 comments:

Chris Percival said...

Ran into this myself today, great post, thanks!

comment system said...

I've been looking for this guide post for hours! thank you so much, I just tried the second solution and it worked like a charm! thanks!

MGD King said...

You my friend, are a genious!!! I've been banging my head against the monitor for nearly two days!!

Brian said...

I tried the second solution and it did resolve the 500.22 error, but it seems that it did not solve the problem completely. When I got to my main page it complained that one of the handlers in the system.webserver section was not registered. If I don't wrap that section in location tags everything works perfectly.

shelly-skeens said...

Nice one. I found this blog looking for another problem I'm having with an IIS7 sub-application. I realized I hadn't tested my main application after setting up the sub-application...and voila! The error and the solution in one neat package. Thanks!

shelly-skeens said...

A followup: wrapping system.webserver in a location tag ended up breaking my parent application's extensionless URL's (set up using the URL Rewrite module). It could be something amiss with my rewrite rules...I hate regex...but I ended up removing the system.web handlers and modules and dispensing with validateIntegratedModeConfiguration. I then removed and added handlers and modules required for my sub-application. Not the most elegant solution, but it works. If anyone has any idea why the location tag might break extensionless URL's, please post.

Thanks still for a great explanation of the overall problem.

Nithin said...

I cant leave this page without a comment, Because this article solved my problem, which i was searching for a solution for last 2 days.

The first solution worked for me. Now pages loading perfectly.

Once again Many many thanks for this article. Keep on helping others.....

Anonymous said...

Thank You so much! The second solution worked for me.