IIS Rewrite, rewrite maps and query strings

Please help me understand rewrite maps, I have this setup:

<rewriteMap name="MyMap">
   <add key="/pages" value="/website/pages/index.aspx" />
   <add key="/pages/page-1" value="/website/pages/page-1/index.aspx" />
   <add key="/pages/page-1/section-1" value="/website/pages/page-1/section-1.aspx" />
</rewriteMap>

Here is my rule:

<rule name="Rewrite rule for MyMap" stopProcessing="true">
   <match url=".*" />
   <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
      <add input="{MyMap:{REQUEST_URI}}" pattern="(.+)" />
   </conditions>
   <action type="Rewrite" url="{C:1}" appendQueryString="true" />
</rule>

This is working if I try to access these pages:

  • www.mydomain.com/pages (OK)
  • www.mydomain.com/pages/page-1 (OK)
  • www.mydomain.com/pages/page-1/section-1 (OK)

But I want the possibility to add a query string on any of these pages, example:

  • www.mydomain.com/pages?page=1 (FAIL)

When I try to access this page, I get a 404. How can I get this to work?


By default URL rewrite rules using rewrite maps are created matching on the {REQUEST_URI} variable. This includes the URL + the query string. This allows you to match against URLs with query string parameters and rewrite them to other pages. Very handy but this is apparently not what you want/need.

You want to only match against the URL, without the query string. In order to change this you have to replace {REQUEST_URI} in the condition to {URL}. Then only the URL (without query string) will be matched against the rewrite map. You can then add the query string to the rewritten URL so that the executed script still has access to it.

You end up with a rule like:

<rule name="Rewrite rule for MyMap">
    <match url=".*" />
    <conditions>
        <add input="{MyMap:{URL}}" pattern="(.+)" />
    </conditions>
    <action type="Rewrite" url="{C:1}" appendQueryString="true" />
</rule>

Instead of using

<add input="{MyMap:{URL}}" pattern="(.+)" />

you can also try

<add input="{MyMap:{SCRIPT_NAME}}" pattern="(.+)" />

See here:

Can't get static redirects to work with IIS Url Rewrite 2.0