When configuring ASP.NET applications in IIS, there are actually two distinct places where .NET Framework versions are specified:
1. Server-level ".NET Framework Version" setting (the subject in question)
2. Application Pool ".NET CLR Version" setting
This global setting primarily affects:
- ISAPI filter mappings for ASP.NET file extensions (.aspx, .ashx, etc.)
- The version of aspnet_isapi.dll that gets loaded
- Machine-wide compilation behavior for ASP.NET 2.0+ applications
The magic lies in how .NET 4.0 was designed to be backward-compatible. When you see this behavior:
Server Setting: v2.0
App Pool CLR: v4.0
Result: The application runs under CLR 4.0 while using ASP.NET 2.0 ISAPI mappings
This works because .NET 4.0 introduced the concept of "in-place side-by-side" execution.
Consider these scenarios requiring adjustment:
// Classic ASP.NET 1.1 applications
if (legacyAppRequiresV1_1) {
// Must set both server-level and app pool to v1.1
iisConfig.SetFrameworkVersion("1.1");
appPool.SetCLRVersion("1.1");
}
// ASP.NET Core reverse proxy scenarios
if (runningBehindANetCoreApp) {
// Should set server-level to "No Managed Code"
iisConfig.RemoveManagedHandler();
}
This setting modifies the following in applicationHost.config:
<system.webServer>
<asp install="true" />
<isapiFilters>
<filter name="ASP.Net_2.0.50727" path="%windir%\..." enabled="true" />
</isapiFilters>
</system.webServer>
- Leave at v2.0 for most mixed environments
- Set to "No Managed Code" for pure ASP.NET Core hosting
- Only specify v4.0 when explicitly required by legacy components
Watch for these symptoms when the setting is misconfigured:
HTTP Error 500.23 - Internal Server Error
(An ASP.NET setting has been detected that does not apply...)
Resolution:
1. Check server-level setting matches app requirements
2. Verify handler mappings in web.config
3. Compare framework versions in IIS and project files
Many administrators encounter this setting in IIS Manager but rarely change it from its default v2.0 value. The ".NET Framework Version" dropdown at the server level actually controls the ISAPI filter pipeline version for classic ASP.NET applications, not the CLR version for managed code.
This setting determines:
1. The version of aspnet_isapi.dll that handles requests
2. The ISAPI filter pipeline behavior
3. The machine.config/root web.config version used for non-application-pool contexts
While application pools specify the CLR version for managed code execution, this server-wide setting affects:
- Classic mode ISAPI request processing
- Global configuration file resolution
- Pre-application startup behaviors
Here's how to check current settings via PowerShell:
# Get server-wide .NET version setting
Get-WebConfigurationProperty -Filter "/system.webServer/asp" -Name "runtimeVersion"
# Compare with application pool settings
Get-ChildItem IIS:\AppPools | Select-Object Name, ManagedRuntimeVersion
Consider modifying this setting when:
- Deploying ASP.NET Core modules that require v4.0 pipeline
- Running mixed classic/integrated mode applications
- Encountering ISAPI-related compatibility issues
Watch for these signs indicating a version mismatch:
- HTTP 500.19 errors referencing wrong framework version
- ISAPI filters failing to initialize
- Configuration inheritance problems in child applications
For modern deployments:
1. Set server-level to v4.0 unless requiring legacy support
2. Configure application pools individually
3. Verify using the ApplicationHost.config file's <asp> section
The setting modifies this section in ApplicationHost.config:
<system.webServer>
<asp runtimeVersion="4.0.30319" />
</system.webServer>
Understanding this distinction helps troubleshoot obscure framework version conflicts in complex IIS environments.