Custom 404 page redirect not working in IIS7.5 when missing URL is in a sub-folder

asp.nethttp-status-code-404iis-7redirectweb.config

I have a site with a mixture of .html and .aspx pages running on a W2K8 R2 server with IIS 7.5. The site is a redevelopment of an older site and all of the URLs and most of the content has changed from the old site to the new site. I expect to get a number of 404s as people use old links.

I want to redirect 404 errors to a custom page (/404.aspx). This is (part) of my web.config:

  <system.web>
    <customErrors mode="On" redirectMode="ResponseRewrite"> 
      <error statusCode="404" redirect="/404.aspx" />
    </customErrors>
  </system.web>
  <system.webServer>
    <httpErrors errorMode="Custom" existingResponse="Replace">
      <remove statusCode="404" subStatusCode="-1" />
      <error statusCode="404" prefixLanguageFilePath="" path="/404.aspx"  
             responseMode="ExecuteURL" />
    </httpErrors>
  </system.webServer>

The managed pipeline mode for the App Pool for this site is Integrated.

This redirection to my custom 404.aspx page is working well some of the time, and other times it is only kind of working. These kind of URLs redirect just fine:

However, these kind of URLs (where the missing page is in a sub-folder) get a strange result:

What happens with the sub-folder URLs is I get the HTML markup from the 404.aspx page, but the page doesn't render properly because all of the CSS and script references in the page are missing, near as I can tell from sniffing network traffic, because somehow IIS is trying to insert the /folder/ into the URL for resources with relative paths in my 404.aspx page. For example, my 404.aspx page, which is in my site's root folder has a reference to css/style.css but for a 404 page triggered by a missing page in /folder/, the browser is trying to download: /folder/css/style.css – which obviously isn't there.

Does anyone know what I'm doing wrong here?

Best Answer

You could use an absolute path (start with forward slash from the root of your site) to reference the stylesheets:

<link rel="stylesheet" href="/css/style.css" type="text/css" />

Or you can use root-relative URLs (start with tilde and forward slash). If the <link>-element is in a <head runat="server">-element then the root-relative URL will be translated to the right client-side relative path.

<head runat="server">
  <link rel="stylesheet" href="~/css/style.css" type="text/css" />

For scripts you have to resolve root-relative URLs yourself. Use the System.Web.UI.Page's ResolveUrl() method:

<script type="text/javascript" src="<%= ResolveUrl("~/scripts/script.js") %>"></script>

Or you may just have to set responseMode to redirect in your configuration.

Related Topic