IIS URL Rewrite: Add trailing slash except for .html and .aspx

36,062

Solution 1

If you want something done right, you've got to do it yourself, obviously...

Here is the solution to my question:

<rule name="Add trailing slash" stopProcessing="true">
  <match url="(.*[^/])$" />
  <conditions>
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    <add input="{REQUEST_FILENAME}" pattern="(.*?)\.html$" negate="true" />
    <add input="{REQUEST_FILENAME}" pattern="(.*?)\.aspx$" negate="true" />
  </conditions>
  <action type="Redirect" redirectType="Permanent" url="{R:1}/" />
</rule>

Update: I blogged about this in more detail.

Solution 2

Varying the other answers, I used this so I wouldn't have to specify a list of file extensions:

<!-- Ensure trailing slash -->
<rule name="Add trailing slash" stopProcessing="true">
  <match url="(.*[^/])$" />
  <conditions>
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    <add input="{REQUEST_FILENAME}" pattern="(.*?)\.[a-zA-Z]{1,4}$" negate="true" />
  </conditions>
  <action type="Redirect" redirectType="Permanent" url="{R:1}/" />
</rule> 

Solution 3

We add multiple extensions like this:

<add input="{URL}" negate="true" pattern="((.+).(jpg|ico|gif|js|png|htm|css|html))" ignoreCase="true" />

Solution 4

To prevent all files from having a slash added, I changed the match rule to this:

<match url="^([^.]*[^/])$" />

That applies the rule only to paths that include any number of non-dot characters that does not end in a slash. So any path that includes a dot (e.g. xxx.html, xxx.aspx, etc.) would be excluded without needing any additional negation rule.

Looking for the presence of a dot in the match rule allowed me to completely remove the condition rules that use match types IsFile and IsDirectory. Those match types are only allowed in distributed rules (web.config), not in the global rules (applicationHost.config), so I had been forced to replicate this rule for every site instead of applying it to all sites using a global rule. By modifying the regex in the match rule to exclude files and removing the IsFile and IsDirectory conditions, I was able to create a global rule instead of having multiple distributed rules.

Solution 5

            <conditions>
                <add input="{URL}" pattern="(.*)\.(.*)[a-z]$" negate="true" />
                <add input="{URL}" pattern="(.*)\.(.*)[0-9]$" negate="true" />
            </conditions>

except for .html and .aspx and .woff2

Share:
36,062
Seb Nilsson
Author by

Seb Nilsson

Software Developer with focus on ASP.NET &amp; C# Passionate about the web, HTML5 &amp; JavaScript Active within Microsoft-technologies and Open Source Sharing knowledge from own projects

Updated on November 11, 2020

Comments

  • Seb Nilsson
    Seb Nilsson over 3 years

    Adding a trailing slash to all URLs through IIS URL Rewrite Module is widely spread, but how do I add exceptions for URLs that ends with .html and .aspx?

    Today I have this:

    <rule name="Add trailing slash" stopProcessing="true">
      <match url="(.*[^/])$" />
      <conditions>
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
        <!-- Doesn't seem to be working -->
        <!--<add input="{REQUEST_URI}" pattern="(.*?).html$" negate="true" />-->
        <!--<add input="{REQUEST_URI}" pattern="(.*?).aspx$" negate="true" />-->
      </conditions>
      <action type="Redirect" redirectType="Permanent" url="{R:1}/" />
    </rule>
    
  • Micah
    Micah over 11 years
    This worked for me after installing the URL Rewrite module: iis.net/downloads/microsoft/url-rewrite
  • IntricatePixels
    IntricatePixels about 11 years
    +1 this fixed an issue I was having in Wordpress (running on IIS) where the W3 Total Cache plugin was caching blank pages when trailing slash was missing.
  • Alex Czarto
    Alex Czarto about 7 years
    Why are you negating matchType="IsDirectory"? Isn't this precisely the case where a trailing slash should be added?
  • Vishal Sen
    Vishal Sen almost 6 years
    this is worked for me , thanks for saving my time. :)
  • Elinoter99
    Elinoter99 almost 5 years
    @micah Would you know why images wont load (500) when this rule is applied?
  • J. Murray
    J. Murray over 4 years
    Can you comment on why this Answer works a little? Solutions are always accepted, but knowing why is just as important as the fix :)