Wildcard script mapping and IIS 7 integrated pipeline

The big benefit of IIS 7 integrated request processing pipeline is the fact that all the nice and useful ASP.NET features can be used for any type of content on your web site; not just for ASP.NET-specific content. For example, ASP.NET SQL-based membership can be used to protect static files and folders. Also, ASP.NET extensibility API’s, such as IHttpHandler and IHttpModule can be used to add custom modules and handlers that would be executed even for non-ASP.NET content.

IIS 6 did not have this level of integration. ASP.NET was plugged into IIS 6 as an ISAPI extension and by default was configured to handle ONLY requests mapped to that extension – for example any request that ended with “.aspx” would be be processed by ASP.NET extension. This obviously was a big limitation for customers who wanted to be able to use ASP.NET features for all other contend on web site. The most common way to workaround that was to use “Wildcard script mapping”. This post explains how an application that used wildcard script mapping in IIS 6 can be migrated over to IIS 7.

Assume you had configured ASP.NET in IIS 6 to handle all requests by using wildcard script mapping. For example you had an ASP.NET module for URL rewriting and you wanted this module to handle extension-less URLs.

This wildcard script map configuration is typically done within IIS 6 manager by opening the properties dialog for either web server or web site and selecting Home Directory tab, then clicking on Configuration button and then clicking on the Insert button for “Wildcard application maps”:

WildcardIIS6

Now, as you move your application to IIS 7, you want to configure it to achieve the same behavior of ASP.NET. There are two options on how this can be done: using Classic pipeline mode or using Integrated pipeline mode.

Wildcard script mapping in IIS 7 classic pipeline mode

With classic pipeline mode the ASP.NET is plugged into the IIS request processing pipeline as an ISAPI extension – exactly the same way as it was in IIS 6. In fact, if you open %WINDIR%\system32\inetsrv\config\applicationHost.config file and locate the <handlers> section inside of it you can see how IIS is configured to map ASP.NET specific requests to the aspnet_isapi.dll:

<handlers accessPolicy="Read, Script">
  ...
  <add name="PageHandlerFactory-ISAPI-2.0"
       path="*.aspx" verb="GET,HEAD,POST,DEBUG"
       modules="IsapiModule"
       scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll"
       preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
  ...
</handlers>

Notice the preCondition attribute for the handler mapping. Among other things this attribute is set to classicMode, which ensures that this handler mapping only takes effect when the application pool is configured to run in classic mode.

Now if you want to configure wildcard mapping for the ASP.NET running in classic mode, you can add one more handler mapping to the <handlers> section just before the handler mapping for static files:

<handlers accessPolicy="Read, Script">
  ...
  <add name="ASP.NET-ISAPI-2.0-Wildcard"
     path="*" verb="GET,HEAD,POST,DEBUG"
     modules="IsapiModule"
     scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll"
     preCondition="classicMode,runtimeVersionv2.0,bitness32" responseBufferLimit="0" />
  <add name="StaticFile"
     path="*" verb="*"
     modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule"
     resourceType="Either" requireAccess="Read" />
</handlers>

The relative order of the wildcard handler mapping is important: if you define this handler mapping after the “StaticFile” handler mapping then “StaticFile” will handle all the requests and no requests will ever come to ASP.NET wildcard handler.

As you may already know the ASP.NET wildcard handler mapping in IIS 7 is subject to the same performance limitations as existed in IIS 6. The problem with this kind of handler mapping is that ALL requests are processed by it, including requests for static files. The ASP.NET static file handler is not as powerful as native IIS static file handler. Plus static files served by ASP.NET will not be cached by IIS in kernel mode. Because of these performance limitations it is recommended that you use IIS 7 integrated pipeline to achieve the same functionality as with wildcard mappings in IIS 6.

IIS 7 integrated pipeline instead of wildcard script mapping

With integrated pipeline, the ASP.NET functionality is fully integrated into the main request processing in IIS, which means that all ASP.NET features are now available for any type of requests. This effectively eliminates the need for the wildcard handler mapping. Now you can use your existing ASP.NET modules and have them applied to all requests.

For example let’s say you had a URL rewriting module written in ASP.NET. On IIS 6 this module was registered inside of the <system.web> section in web.config file as below:

<system.Web>
  <httpModules>
    ...
    <add name="MyUrlRewrite"
         type="SomeNamespace.MyModules.UrlRewrite, SomeNamespace.MyModules" />
    ...
  </httpModules>
</system.Web>

Since on IIS 6 this module was only executed for requests to managed content, it only worked for URLs that had .aspx extension, such as http://example.com/archive/2008/08/26/post-title.aspx. If you wanted it to handle extension-less URLs you had to configure wildcard script mapping for ASP.NET. With IIS 7 integrated pipeline you do not have to do that anymore. In order to make this module apply to extension-less URLs you need to register it within the <system.webServer> section inside of web.config file as below:

<system.webServer>
  <modules >
    ...
    <add name="MyUrlRewrite"
         type="SomeNamespace.MyModules.UrlRewrite, SomeNamespace.MyModules"
         preCondition="" />
    ...
  </modules>
<system.webServer>

Make sure that you leave the preCondition attribute empty here as it would enforce that the module will be executed for all requests, not just for requests for ASP.NET specific content.

Registering your managed modules this way does not have such dramatic performance impact as when using wildcard script mappings. Even though the module is invoked for all requests to web application, all the existing handler mappings are still in effect, which means that the static files are still served by the native IIS static file handler. Another benefit of registering your module this way is that now it can be applied to requests for PHP, ASP or any other dynamic pages. You would not be able to do that if you used wildcard script mappings.

One last thing to mention here is that you can also use the attribute on the <modules> section called runAllManagedModulesForAllRequests.

<system.webServer>
  <modules runAllManagedModulesForAllRequests="True" >
    ...
    <add name="MyUrlRewrite"
         type="SomeNamespace.MyModules.UrlRewrite, SomeNamespace.MyModules"
         preCondition="ManagedHandler" />
    ...
  </modules>
<system.webServer>

This attributes forces IIS to ignore the preCondition=”managedHandler” attribute, hence all managed modules will be invoked for all requests to web application.

8,695 views

ruslany on September 30th 2008 in Other

PoorFairAverageGoodExcellent (8 votes, average: 4.50 out of 5)

12 Responses to “Wildcard script mapping and IIS 7 integrated pipeline”

  1. Gravatar ImageTarique responded on 16 Feb 2009 at 3:08 pm #

    Hi,

    I liked your article. It gave me a better understanding of IIS 7.

    I am in a similiar scenario to the one you mentioned, that is i have an asp.net module for url rewriting and had wild card mapping in IIS 6.

    I had extensionless url’s .. like http://www.xxx.com/sports which got mapped to http://www.xxx.com/sports/pag1.aspx

    and I had extension url’s … like http://www.xxx.com/sports/football.aspx which got mapped to http://www.xxx.com/sports/default.aspx?Sport=football

    Now i’m trying to move to IIS 7 and i couldn’t get the url rewriter to work at all. Neither the extionless urls or the extension urls which used url’s rewriting worked.

    I read your article and tried the classic mode approach. The extension url’s like http://www.xxx.com/sports/football.aspx started working. But the extensionless url’s like http://www.xxx.com/sports would get redirected to http://www.xxx.com/sports/ and the http://www.xxx.com/sports/default.aspx would be shown.

    I was wondering if you had any idea of what i’m doing wrong.

    Thnx,

    Tarique

  2. Gravatar ImageTarique responded on 16 Feb 2009 at 4:13 pm #

    Hi again,

    I tried using the integrated pipeline approach. Like in the previous case, the extensions with url’s are getting rewritten properly.

    However, again having problem with extensionless url’s:

    This time if i type in http://www.xxx.com/sports, i get the error:

    System.Web.HttpException: Session state can only be used when enableSessionState is set to true, either in a configuration file or in the Page directive. Please also make sure that System.Web.SessionStateModule or a custom session state module is included in the \\ section in the application configuration.

    Again if i type in the real page name http://www.xxx.com/sports/page1.aspx, it shows up fine.

    Any idea of what i’m doing wrong ?

  3. Gravatar Imageruslany responded on 16 Feb 2009 at 6:52 pm #

    Tarique, have you tried setting runAllManagedModulesForAllRequests=”true”?

  4. Gravatar ImageTarique responded on 18 Feb 2009 at 6:46 am #

    Hi,

    I tried the runAllManagedModulesForAllRequests=”true” and got it to work.

    Do you know what this attribute does ?(Will it have a performance impact? and why i got the error message without the tag?

    Also, any ideas on how i could get the wild card mapping to work in the classic mode ?

    I’d appreciate any help you could give me.

  5. Gravatar Imageruslany responded on 18 Feb 2009 at 10:18 am #

    I think you’ve got the error message before because your application was relying on some other managed module (Session) and that module was configured to run only for requests to managed handler.

    You can try the following steps:
    1. Remove the runAllManagedModulesForAllRequests attribute (or set it to false).
    2. Re-configure the Session module to run for all requests:

    <modules>
    <remove name="Session" />
    <add name="Session" type="System.Web.SessionState.SessionStateModule" preCondition="" />
    </modules>

  6. Gravatar ImagePensieve: IIS 7 Wildcard mapping issues responded on 24 Mar 2009 at 10:53 am #

    [...] logged out when at /. It turns out this is the source of that problem too.The answers are out there, I just had a hell of time finding them so I thought I would re-share. digg_url = [...]

  7. Gravatar ImageJonas Eriksson responded on 25 Jun 2009 at 11:51 pm #

    Hi! I went the classic pipeline way, but had problems with my static files (.css,.js,.jpg,.gif et.c). My solution was to add static handlers for each extension above the isapi handler. Was there another option?

  8. Gravatar ImageGeorge Sazandrishvili responded on 27 Jun 2009 at 7:41 am #

    Hello,

    Thank you for this post. It is very informative and extremely helpful, especially for those who are moving or have just moved to IIS 7 and have not yet had time to fully understand IIS 7.

    Best wishes,
    George

  9. Gravatar Imageruslany responded on 29 Jun 2009 at 12:45 pm #

    Jonas, what exactly was the problem with static files? Did all requests to static files result in 500 status code?

  10. Gravatar ImageAdam responded on 05 Aug 2009 at 12:52 pm #

    If you still have the session-breaking issue that requires removing and re-adding the session module to fix, that won’t be changing any time soon. Microsoft has deemed this behavior by design and closed the bug on Connect.

  11. Gravatar Imagegices responded on 03 Oct 2009 at 10:21 am #

    Mine doesn’t work either even with runAllManagedModulesForAllRequests=”true”. It used to work before but now nothing gets to the httpmodule on iis7. Maybe some updates to iis7 caused it to stop working?

  12. Gravatar Imageruslany responded on 05 Oct 2009 at 10:30 pm #

    @gices: this is strange, especially if you say that it used to work before. Is this on the windows server 2008 or 2008 R2?

Trackback URI | Comments RSS

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

XML Markup: If You want to add XML code to the comment please XML encode it first, otherwise the code will not show up.

Recently Published Articles