IIS 7.0–Integrated Mode and Classic Mode

Recently we rolled out a .net Framework 4.0 project which used the entity framework mapping to the database objects. However when it published on the IIS 7, it gave the error: 500 – Internal server error. As this error is too general, also the IIS logs didn’t give much clues either. I spent a few hours (tried checking .net Framework setting, application pool setting, site setting etc.) to find the tricky as it seems all other settings are correct. Eventually I found, if change the default setting “Integrated” mode to “Classic” mode, those aspx pages were able to display no problem. The question comes
1. What is the difference between the two modes?
2. Should “Class” mode be used in this case or something is wrong?

First question answer:

Integrated application pool mode

When an application pool is in Integrated mode, you can take advantage of the integrated request-processing architecture of IIS and ASP.NET. When a worker process in an application pool receives a request, the request passes through an ordered list of events. Each event calls the necessary native and managed modules to process portions of the request and to generate the response. There are several benefits to running application pools in Integrated mode. First the request-processing models of IIS and ASP.NET are integrated into a unified process model. This model eliminates steps that were previously duplicated in IIS and ASP.NET, such as authentication. Additionally, Integrated mode enables the availability of managed features to all content types.

Classic application pool mode

When an application pool is in Classic mode, IIS 7.0 handles requests as in IIS 6.0 worker process isolation mode. ASP.NET requests first go through native processing steps in IIS and are then routed to Aspnet_isapi.dll for processing of managed code in the managed runtime. Finally, the request is routed back through IIS to send the response. This separation of the IIS and ASP.NET request-processing models results in duplication of some processing steps, such as authentication and authorization. Additionally, managed code features, such as forms authentication, are only available to ASP.NET applications or applications for which you have script mapped all requests to be handled by aspnet_isapi.dll. Be sure to test your existing applications for compatibility in Integrated mode before upgrading a production environment to IIS 7.0 and assigning applications to application pools in Integrated mode. You should only add an application to an application pool in Classic mode if the application fails to work in Integrated mode. For example, your application might rely on an authentication token passed from IIS to the managed runtime, and, due to the new architecture in IIS 7.0, the process breaks your application.

Final Solution

After the clarification for the first question, it just let me feel more confused. As “Integrated” mode is the IIS 7.0 default mode and under this mode, the performance will be maximum, then why this .net 4.0 project only can run under classic mode. After some research again, I found the root reason is due to one wrong configuration in web.config file of this project which is “identity impersonate=”true””, the explanation is as below. As in this project I can ensure “impersonation” is not applied, so I just removed from web.config, after removing, the project was able to run under “Integrated” mode no problem. Cheers!

You will receive a 500 – Internal Server Error. This is HTTP Error 500.24: An ASP.NET setting has been detected that does not apply in Integrated managed pipeline mode. This occurs because ASP.NET Integrated mode is unable to impersonate the request identity in the BeginRequest and AuthenticateRequest pipeline stages. Workaround

B. If your application does rely on impersonation in BeginRequest and AuthenticateRequest, or you are not sure, move to Classic mode.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <connectionStrings>   
    <add name="Al_Entities" connectionString="metadata=res://*/Al_DataModel.csdl|res://*/Al_DataModel.ssdl|res://*/Al_DataModel.msl;provider=System.Data.SqlClient;provider connection string=&quot;data source=ServerName\Instancename;initial catalog=Al_table;integrated security=True;multipleactiveresultsets=True;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>

  <system.web>
    <compilation debug="true" targetFramework="4.0">
		<assemblies>
			<add assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
		</assemblies>
    </compilation>
    <authentication mode="Forms">
      <forms loginUrl="~/Account/Login.aspx" timeout="2880" />
    </authentication>
    <membership>
      <providers>
        <clear />
        <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" />
      </providers>
    </membership>
    <profile>
      <providers>
        <clear />
        <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/" />
      </providers>
    </profile>
    <roleManager enabled="false">
      <providers>
        <clear />
        <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
        <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
      </providers>
    </roleManager>    
	<customErrors mode="Off"/> 

 <identity impersonate="true" />
  </system.web>

  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true" />
		<asp scriptErrorSentToBrowser="true"/>
        <defaultDocument>
            <files>
                <clear />
                <add value="default.aspx" />                
            </files>
        </defaultDocument>
  </system.webServer>
</configuration>

IIS 7 Configuration

There are a lot of website to explain or introduce the IIS 7 configurations, but none of them contains more details than the Microsoft official website. This page list the IIS features and configurations by administration task, site configuration request etc.

http://technet.microsoft.com/en-us/library/cc732976(v=ws.10).aspx

Some example regular settings.

1. Check if .net 4.0 Framework is available.
Under “Connections” Panel, find IIS server node, at the feature view on the right, double click “ISAPI and CGI Restrictions”, all the supposed framework have been listed, and you need to ensure the “ASP.NET v4.0.30319” Restriction set to “Allowed”

2. Define error pages.
Under “Connections” Panel, find the proper level node, at the feature view on the right, double click “Error pages”, and all the system defined error pages will show up.

3. Setup website or virtual directory application pool
Under “Connections” Panel, find the proper level node, right click the node, select “Manage Application”-> “Advanced Settings” , in the popup window you can define the application pool from the dropdown list.

4. Setup the “Integrated” mode or “Classic” mode and .net Framework.
Under “Connections” Panel, find the “Application Pools”, pick up the pool you want to define. Right click the “Basic Setting” or “Advanced Settings”, in the popup window, you can define the .net Framework and Managed pipeline mode.