Dave Donaldson

Critical thinking in software development

Search

Advertisement

Subscribe

Follow Me

TwitterCounter for @arcware

My Tweets

  • Just went flying off the road. No lie. More soon.
  • Planning to watch the OSU-MichSt in the bar, if anyone wants to join, but will be late
  • Geeking out with @fallenrogue and @danhounshell on way to #codemash
  • Watching Spongebob while I wait for @fallenrogue and @danhounshell.
  • Re-syncing my entire 30GB Zune.

Use a Single Web.Config for IIS6 and IIS7

Tuesday, April 08 2008

As we near closer and closer to the release of Community Server 2008, one of the items that needed addressed was making sure it runs in IIS7 Integrated Pipeline mode. If you're not familiar with it, IIS7 is quite different from previous versions of IIS, and provides two modes of operation: the aforementioned Integrated Pipeline mode and a Classic Pipeline mode. Running an ASP.NET site in Integrated Pipeline mode means you're taking full advantage of all the new features and underlying architecture of IIS7. On the other hand, running an ASP.NET site in Classic Mode basically means you want the site to operate as if it were running in IIS6.

The primary issue with running an ASP.NET site in IIS7 Integrated Pipeline mode is if you have any HTTP modules configured. See, the "problem" is that with ASP.NET under IIS6, there were essentially two pipelines: one for ASP.NET and one for IIS. A request would come into IIS and if the file extension was mapped to the ASP.NET ISAPI extension, the request would be passed off to aspnet_isapi.dll and was then processed by the ASP.NET pipeline, which is where the HTTP modules come into play with regards to events that occur in the pipeline. However, in IIS7 there is only one pipeline for those events, and its used for both IIS7 native modules and ASP.NET modules (once the pipeline events have been taken care of, the file is taken care of by the appropriate ISAPI extension).

Now that we've covered that, if your ASP.NET app has HTTP modules and you want to make sure it runs in both IIS6 and IIS7 Integrated Pipeline mode (from here on out just referred to as IIS7), you need to make some changes to web.config (there are other things to consider as well when running an ASP.NET site under IIS7, so definitely check out this article first for details). The web.config changes needed are for your HTTP modules and handlers. For IIS6, they were configured in the <system.web> section, as such:

<system.web>
    </httpModules>
        <add name="..." type="..." />
    </httpModules>
    <httpHandlers>
        <add verb="...." path="..." type="..." />
    </httpHandlers>
</system.web>

 

However, to get these to work in IIS7 you must *move them* from the <system.web> section to the new <system.webServer> section, which is what IIS7 requires when running in Integrated Pipeline mode (it's not needed for Classic Pipeline mode). So instead of the above you'd have this instead:

 

<system.webServer>
    </modules>
        <add name="..." type="..." />
    </modules>
    <handlers accessPolicy="Read, Write, Script, Execute">
        <add verb="...." name="..." path="..." type="..." />
    </handlers>
</system.webServer>

 

Notice there are a couple slight changes, which means you can't just copy and paste these as-is from <system.web> into <system.webServer>:

  • <httpModules> and <httpHandlers> have been renamed to <modules> and <handlers>, respectively.
  • Each handler in IIS7 requires a name attribute. If you don't specify it, you'll get an error message.
  • The handlers node has an optional, but good-to-define accessPolicy attribute. This value depends on your handlers, so use the ones that are right for you.

Armed with this knowledge, to run your ASP.NET app on IIS6 and IIS7 you could simply create a web.config for each version and then deploy the appropriate version to each IIS web server as needed. That's a reasonable solution, but there is a way to use a single web.config to run your ASP.NET app on both IIS6 and IIS7: 1) configure your HTTP modules and handlers in both the <system.web> and <system.webServer> sections, and then 2) tell IIS7 to skip validation of the Integrated Pipeline mode configuration.

 

The way you do that is by adding a <validation> node to your <system.webServer> section and set its validateIntegratedModeConfiguration attribute to false, as such:

 

<system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules>
        <add name="..." type="..." />
    </modules>
    <handlers accessPolicy="Read, Write, Script, Execute">
        <add verb="..." name="..." path="..." type="..." />    
    </handlers>
</system.webServer>

 

If you don't turn that validation off, IIS7 will try to validate the *configuration* of the Integrated Pipeline mode for your app, which would fail if you have your HTTP modules and handlers also defined in the <system.web> section (because for IIS7 they should only be defined in <system.webServer>). But by turning that validation off, IIS7 won't throw the error, thus allowing you to get away with defining your HTTP modules and handlers in both places.

 

The reason this works is because only one set of defined modules and handlers can be loaded. For ASP.NET sites running under IIS6, this will only be the ones defined in <system.web>, which go into the ASP.NET pipeline, while ASP.NET sites in IIS7 will only get the ones defined in <system.webServer>, which actually go into the IIS7 pipeline.

 

And there you go. Configure your HTTP modules/handlers in both the <system.web> and <system.webServer> sections and turn off validation of the Integrated Pipeline mode and you can use a single web.config for running ASP.NET sites in IIS6 and IIS7. I've tested this with IIS6, IIS7 Classic Pipeline mode, and IIS7 Integrated Pipeline mode all without issue (and yes, Community Server will run in IIS7 just fine) so I know it works.

 

Mad props to my friend and IIS7 Evangelist Drew Robbins about this issue as he definitely helped clear some of the confusion.

Similar Posts

  1. Using svn:externals to Manage Project References
  2. NHibernateRepository
  3. Compare Assemblies with BitDiffer

6 comment(s) so far

Great Post! Thanks for the information!

Thanks Jim.

Thank you so much Dave for this post!! It helped me a lot... llevaba varios dias luchando con un error en el IIS.

Thomas wrote on Tuesday, December 16 2008

Really great hints! Thanks

I’ve never actually written a “Top X Posts” post to end the year before, so I figured, what the heck, I’ll do one this year. As Phil points out , “I find that somewhat narcissistic, so you know I’m going to do that”.

I’ve never actually written a “Top X Posts” post to end the year before, so I figured, what the heck

Post your comment

Comment