For many of us familiar problem. You developing applications under IIS6 and you're about to move them to IIS7. In previous version of IIS was enough to copy over your files, create app pool and site. IIS7 (7.5) is different in this point.
In IIS6 there was only one way hot to extend server with other features – using ISAPI filters. Whole .NET is lived within one dll aspnet_isapi.dll. If the request was for files with .NET type extensions (such .aspx, .ashx, .axd and so on) your application know them and was able to serve them. If request was for file with extension for example .jpg or other static file, the application was not aware about them. For example this is the reason why URL authorization does not work for static files.
IIS7 offers two modes of work:
- Classic – In IIS requests are processed by above description. Basically the system is compatible with previous versions of IIS
- Integrated – the default one. In this mode has IIS privileged position, the HTTP handlers and modules (known from ASP.NET) can be executed directly. They are in line with ISAPI filters and built-in IIS functionality.
HTTP handlers, modules were not changed at all, so you don't need to rewrite or recompile them. But was has been changed is the way how to know IIS about which handler, module to use. Basically this is often problem when app is running properly under IIS6 but won't under IIS7. This is not such difference between IISs but it's big difference between Classic and Integrated mode on application pool. You have two options:
- Put your application under Classic managed pool (this is not recommended, use it only in case when other solutions fails)
- Change the registration of modules and handlers in web.config file to reflect newest configuration schema.
There is no difference whether you register handler or module under IIS6 or IIS7 Classic Mode. Illustration of its registration in web.config:
<?xml version="1.0"?>In case of web.config in II7 Integration mode, registration will looks like:
<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="*My.axd" type="MyHttpHandler"/>
</httpHandlers>
<httpModules>
<add name="MyModule" type="MyHttpModule"/>
</httpModules>
</system.web>
</configuration>
<?xml version="1.0"?>Generally you have to perform these changes:
<configuration>
<system.webServer>
<handlers>
<add name="NameOfMyHandler" verb="*" path="*My.axd" type="MyHttpHandler"/>
</handlers>
<modules>
<add name="MyModule" type="MyHttpModule" preCondition="managedHandler"/>
</modules>
</system.webServer>
</configuration>
- you need rename httpHandlers to handlers and httpModules to modules.
- Handlers has required attribute name, so you have to name them
- Modules should have attribute preCondition with value managedHandler. This is optional and depends on behavior of particular module (module will called only in case when its execution will be driven by handler written in .NET).
HTTP modules are called for each request. In case of II6 or Classic mode it means for each request mapped in aspnet_isapi.dll configuration. For integrated mode it means for all request including for static files.
Well sometimes you run into problem when you your app needs to work IIS6 as well IIS7. Problem is once you register handlers and module in system.webServer section you need to remove their registration from system.web section. If the IIS would ignore old registration in system.web section I could be security risk caused by not executed some modules, handlers. Mostly those for authentication and authorization. But there is am option how to avoid this checking and allow to have registrations in both sections. All you need to do is to turn off validation by attribute validateIntegratedModeConfiguration. Using this attribute is not really recommended.
So the universal web.config for both scenarios would looks like:
<?xml version="1.0"?>Instead of modifying web.config manually, you can perform required changes from command line by
<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="*My.axd" type="MyHttpHandler"/>
</httpHandlers>
<httpModules>
<add name="MyModule" type="MyHttpModule" />
</httpModules>
</system.web>
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<handlers>
<add name="NameOfMyHandler" verb="*" path="*My.axd" type="MyHttpHandler"/>
</handlers>
<modules>
<add name="MyModule" type="MyHttpModule" preCondition="managedHandler"/>
</modules>
</system.webServer>
</configuration>
%windir%\system32\inetsrv\Appcmd migrate config "<ApplicationPath>"
ApplicationPath is site map name in IIS, for example Default Web Site.
The tool will modify web.config in order to move registration of handlers, modules from system.web to system.webServer section.