Some (bad) things in ASP.NET come back from time to time and custom error pages are one of them. A lot has been written on this topic – specifically when using MVC – but I found myself again struggling to get it right. However, I finally got a solution that is a good trade-off. My requirements are similar to everyone’s:
Preserve request URL.
Return proper status code (namely 404 and 500) and content-type.
- Cover IIS errors, since it’s likely that unmanaged stuff is is place (e.g. static file handler).
<httpErrors defaultResponseMode="File" existingResponse="Replace" errorMode="Custom">
<error statusCode="404" path="404.html" />
<error statusCode="500" path="500.html" />
You might need to unlock some attributes on the httpErrors section at machine level. Also, I set errorMode to Custom to always get the custom error pages when testing. In production you’d likely set it to DetailedLocalOnly.
How does it work and what is the trade-off?
The trade-off is between the amount of code/configuration and the flexibility of the resulting error pages. In my solution there’s nothing else to configure or code, but you must use static error pages. This may not give you all the flexibility and duplicates a bit of HTML (some of the site’s layout, assuming that the error pages will look the same), but covers all the error cases. How? The trick is on two of the attributes:
defaultResponseMode=”File” – Ensures that the response content-type is correct and also preserves the status code.
existingResponse=”Replace” – Ensures that any existing response is always replaced by the one configured on httpErrors. This is important because sometimes ASP.NET already produces a response (e.g. not found pages). This option is not usually mentioned on community answers.
So, it doesn’t matter what happened on the server, this configuration will always kick in.
This post is a commonly referenced resource (even by MSFT). It uses a static-ish page approach which configures both ASP.NET custom errors and IIS errors. This works fine, but has more configuration and more code and duplicated HTML.
There’s also a NuGet package to handle 404 on MVC. It wires-up on different MVC extensibility points to catch all the not found situations. You could complement this with the built in HandleErrorAttribute, but it leaves out errors than happen on ASP.NET prior to MVC and IIS errors (e.g. file not found).
If you need to generate the error pages dynamically (using a controller/view), this question on Stackoverflow discusses different alternatives. Note that when you do this, you might get errors when trying to generate the custom error page. Inception! Also, depending on which error configuration section you use, some errors may be left out.
IIS error pages seem to be the less cumbersome solution for custom error pages. If you’re willing to have static HTML pages, it’s probably as good as it gets. I wasn’t able to find any other solution that covers as many cases and is worth the effort.