While trying to set up a custom 404 page for my company website, I found a lot of conflicting information. Use one method, and your
.aspx
pages were handled correctly while other file types still used the IIS default page. Use a different method, and everything BUT
.aspx
pages got your custom message. I spent several hours trying to figure out what I was doing wrong. When the blindingly obvious solution hit, it was physically painful. The answer?
Use both methods.
By design, Internet Information Server suffers from multiple personality disorder, by way of "handler mappings." This allows the web admin to direct http requests through different pre-processing filters based on their file extension. Most requests are handled by a chain of default handlers that decide if the request is a file or a directory and respond accordingly. Requests for
.aspx
files are handled by a special module that goes through the page life cycle; processing that is irrelevant for a
.htm
or .gif file. Each of these types of request look at different parts of the
web.config
for how to treat errors.
ASP.Net pages --
.aspx
files and, I think (untested) old-style
.asp
-- are handled under the
<system.web>
block:
<system.web>
<customerrors mode="On">
<!--
<error statuscode="404" redirect="~/errors/404.aspx" />
</customerrors>
</system.web>
This tells the ASP.Net handler module to use custom errors and, when a code of 404 is generated, redirect the user to a specific page.
All other files that are handled by the default handler chain require a
different setting in the
<system.webServer>
block:
<system.webserver>
<httperrors errormode="Custom">
<!--
<remove statuscode="404" substatuscode="-1" />
<error statuscode="404" prefixlanguagefilepath="">
path="/errors/404.aspx" responseMode="ExecuteURL" />
</error></httperrors>
</system.webserver>
The
<remove />
line tells IIS to remove the default handler for 404; the -1 sub-status means (as far as I can tell) remove all handlers if there are different ones for different sub status codes. The
<error />
inserts the new custom behavior.
The difference, as far as I can tell, is to support different behaviors for ASP and non-ASP pages. In any case, if you want to provide a custom error page regardless of what the user requests, you will need to put both of these blocks into your
web.config
file. You can, of course, use these for any error status such as 401 (Unauthorized), 403 (Forbidden) or 500 (Internal error).
I hope this helps.