4
votes

I am using iis7's URL Rewrite module to accomplish several things:

  • 301 redirect rule from non-www to www
  • 301 redirects rule .info to .com (moved to the .com version of my domain)
  • 301 redirects rule from an old page e.g. /page-name.asp to just /page-name

I have been able to combine the first two into one rule, and the 3rd item is it's own rule. The problem is that two 301 redirects are generated in a case of requesting a url like:

site.info/page-name.asp/

First a 301 is done to:

www.site.com/page-name.asp (e.g. www is added and .info goes to .com)

Then a second 301 is done from that to:

www.site.com/page-name

My question is: how can I combine these so that only ONE 301 redirect occurs instead of two? Here are the two rules as they currently sit in my web.config:

<rule name="SEO - 301 Redirect - .info to .com AND force WWW" stopProcessing="false">
    <match url="(.*)" ignoreCase="true" />
    <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="{HTTP_HOST}" pattern="^site\.info$" />
    </conditions>
    <action type="Redirect" url="{ToLower:http://www.site.com/{R:1}}" redirectType="Permanent" />
</rule>
<rule name=".aspVersion-to-friendlyvia301" stopProcessing="false">
        <match url="(.*).asp" />
        <action type="Redirect" url="{R:1}" />
</rule>
2

2 Answers

7
votes

I seem to have found the answer to my own question. It is a bit of a hack but accomplishes all required url transformations (e.g. trailing slash removal, non-www to www, toLowerCase, removal of default document for directories, and any other redirects necessary such as a page name change).

The problem I was talking about is actually called "chaining of 301 redirects", and the solution is presented rather elegantly, here:

http://www.seomoz.org/blog/what-every-seo-should-know-about-iis#chaining

0
votes

This solution from previous comment:

1) Instead of Redirect apply Rewrite with additional symbol _

2) Add new rule that will catch up URL starts with _ and apply redirect

<rule name="LowerCaseRule1" stopProcessing="false">
      <match url="(.*)" ignoreCase="false" />
      <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="{HTTP_METHOD}" pattern="GET" />
        <add input="{R:1}" pattern="[A-Z]" ignoreCase="false" />
      </conditions>
      <action type="Rewrite" url="_{ToLower:{R:1}}" />
</rule>
<rule name="RemoveTrailingSlashRule1" stopProcessing="false">
      <match url="(.*)/$" />
      <conditions  logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="{HTTP_METHOD}" pattern="GET" />
        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
      </conditions>
      <action type="Rewrite" url="_{R:1}" />
    </rule>
<rule name="Final redirect" stopProcessing="true">
      <match url="^(_+)(.*)" />
      <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
        <add input="{HTTP_METHOD}" pattern="GET" />
      </conditions>
      <action type="Redirect" url="{R:2}" />
</rule>