04 August, 2015

Custom errors in ASP.NET on IIS 7+

I've lost count of the number of times I've had to correct faulty error page implementations in ASP.NET applications. I've seen every combination of customErrors, httpErrors, Application_Error handlers, setting requestValidationMode="2.0" on httpRuntime, and I've seen several applications where request validation was disabled entirely!

Since .NET 4 and IIS 7, we can handle all of our custom error needs in one place, giving us SEO-friendly behaviour without scattering error handling code all over our infrastructure.

First, we edit the httpErrors node in our web.config as follows:-


<configuration>
 ...
 <system .webserver="">
  ...
  <httperrors errormode="Custom" existingresponse="Replace">
   <clear>
   <!-- e.g. if you're using webforms to render your custom error pages -->
   <error responsemode="ExecuteURL" statuscode="400" path="/ServerError.aspx" />
   <error responsemode="ExecuteURL" statuscode="403" path="/ServerError.aspx" />
   <error responsemode="ExecuteURL" statuscode="404" path="/PageNotFound.aspx" />
   <error responsemode="ExecuteURL" statuscode="500" path="/ServerError.aspx" />

   <!-- e.g. if you're using MVC to render your custom error pages -->
   <error statusCode="400" responseMode="ExecuteURL" path="/Error" />
   <error statusCode="403" responseMode="ExecuteURL" path="/Error/Forbidden" />
   <error statusCode="404" responseMode="ExecuteURL" path="/Error/NotFound" />
   <error statusCode="500" responseMode="ExecuteURL" path="/Error" />
  </httperrors>
  ...
 </system>
 ...
</configuration>

This allows us to catch errors from both inside (e.g. application exception) and outside (request validation failure) our application, and render the appropriate custom error page.

The only thing that remains is to make sure that your custom error pages themselves set the correct status code on the response object:-


// in webforms
this.Response.StatusCode = 500; // etc.

// in MVC
public ActionResult Forbidden()
{
 Response.StatusCode = 403;
 return this.View();
}

You can delete the customErrors node entirely, and ensure that request validation is enabled and requestValidationMode="2.0" is note set on the httpRuntime.

You can view the full working httpErrors code on github. There's also a live version on Azure Web Sites.

No comments:

Post a Comment