How Extensionless URLs Are Handled By ASP.NET v4

ASP.NET v4.0 has a new feature, when hosted on IIS 7, that enables the execution of extensionless URLs.  This feature has a dependency on a QFE from IIS that enables extensionless handler mappings.  See KB 980368 for more information and a link to download the fix.

ASP.NET v4.0 adds extensionless handler mappings to IIS's configuration file (applicationHost.config).  There are handler mappings for classic mode and integrated mode.  The classic mode handler mappings map to aspnet_isapi.dll.  The integrated mode handler mappings map to a new type named System.Web.Handlers.TransferRequestHandler.  An example of the handler mappings is below:

 <add
  name="ExtensionlessUrl-ISAPI-4.0_32bit"
  path="*."
  verb="GET,HEAD,POST,DEBUG"
  modules="IsapiModule"
  scriptProcessor="%WINDIR%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll"
  preCondition="classicMode,runtimeVersionv4.0,bitness32" 
  responseBufferLimit="0" />
 <add
  name="ExtensionlessUrl-ISAPI-4.0_64bit"
  path="*." 
  verb="GET,HEAD,POST,DEBUG"
  modules="IsapiModule"   
  scriptProcessor="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll"
  preCondition="classicMode,runtimeVersionv4.0,bitness64"
  responseBufferLimit="0" />
 <add 
  name="ExtensionlessUrl-Integrated-4.0" 
  path="*." verb="GET,HEAD,POST,DEBUG" 
  type="System.Web.Handlers.TransferRequestHandler" 
  preCondition="integratedMode,runtimeVersionv4.0" />

 

These handler mappings are installed when v4.0 is installed, but without the IIS 7 QFE, they are ignored for extensionless URLs.  As soon as you install the QFE, extensionless URLs will enter ASP.NET.  The QFE will eventually be included in a service pack.

In classic mode, extensionless URLs are first mapped to aspnet_isapi.dll by IIS, and then using the <httpHandlers> configuration section, ASP.NET maps them to the System.Web.DefaultHttpHandler.  By default, the root web.config file contains a path="*" mapping to DefaultHttpHandler.  In integrated mode they are mapped to TransferRequestHandler.  DefaultHttpHandler and TransferRequestHandler are similar in what they do.  If you do not remap the handler, they will both issue a "child request" to the original URL, but ask IIS to ignore their handler mappings for this second request.  By default, the IIS StaticFile handler is what will be mapped to these URLs during the second request, and that will typically result in a 404 or 403, assuming that no such file or directory exists.

In order to do something interesting with extensionless URLs, you must remap the handler before the MapRequestHandler event.  To do this, you can call HttpContext.RemapHandler and pass in an instance of IHttpHandler.  At the lowest level, this is how you programmatically remap the handler.  Alternatively use can a feature like URL Routing to remap the handler.  URL Routing allows you to define routes that send a URL to a specific handler.  It simply calls RemapHandler for you.