How to 301 Redirect Old URLs With IIS

Picture shows Jason A. Martin - Software Engineer, Indie Game Developer, Tech Evangelist, Entrepreneur.

Today, as of this writing, I moved my site over to Azure (woot!). I had been wanting to use Azure for some time, but never got around to it. But now that I'm using Azure DevOps, I figured it was time. So, that was the good news.

The bad news was that I changed my site generation tool and had some urls that would no longer be valid. Normally, this would be trivial for me, but I was using an IIS server on Azure and haven't done any Windows server admin since about 2000 (yeah, long time ago). After a lot of trial and error, I finally understood what was going on and I wanted to share the solution with you.

301 Redirect

I'm assuming you know about 301 redirects (moved permanently). If by chance that's not the case, check out this Mozilla Developer Network article:

MDN: Status 301

Read Those Docs

In the chaos of the day, I went to Google to search for answers rather than just going to the source (Microsoft in this case) and looking through docs. Sigh.

After a few hours of "not my problem nor solution" hunting on Google, I "discovered" the IIS docs at docs.microsoft.com and soon after had my answer.

Microsoft Docs: Using Rewrite Maps in Url Rewrite Mode

My 301 Redirect Solution

I am so glad I learned about reWriteMaps. I had a handful of urls to redirect and the thought of building out complete rule entries for each one made me tired.

My app is using Web Apps in Azure, so I just needed to upload a web.config file to my root directory for the new rules to take effect.

Here's an example of that file:

<configuration>
  <system.webServer>
    <rewrite>
      <rewriteMaps>
        <rewriteMap name="StaticRedirects">
          <add key="/2017/08/09/ESO/build-elder-scrolls-online-mod-1" value="/posts/build-elder-scrolls-online-mod-1" />
          <add key="/2017/08/11/ESO/build-elder-scrolls-online-mod-2" value="/posts/build-elder-scrolls-online-mod-2" />
        </rewriteMap>
      </rewriteMaps>
      <rules>
        <rule name="JAM Redirect Rule" stopProcessing="true">
          <match url=".*"/>
          <conditions>
            <add input="{StaticRedirects:{REQUEST_URI}}" pattern="(.+)"/>
          </conditions>
          <action type="Redirect" url="http://www.jasonamartin.com{C:1}" appendQueryString="false" redirectType="Permanent" />
        </rule>
        <rule name="html">
          <match url="(.*)" />
          <conditions>
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Rewrite" url="{R:1}.html" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

The reWriteMap is named StaticRedirects, so that is what I reference in the redirect rule (JAM Redirect Rule).

In case you're curious, the html rule below it is what I use so that my site can have directory endpoints (/some/page) instead of file endpoints (/some/page.html).

Final Thoughts

In case you're going through a search engine looking for IIS 301 redirect answers like I was, I hope you this page has helped you.

And in case you want to dive into the docs more: IIS docs.