Página personalizada de error en asp.net

Me he pegado un montón de rato buscando por ahí... y la solución era obvia:
Necesitaba sustituir la típica página de error de acceso prohibido 403 por algo más personalizado y con un estilo semejante al resto de la web.
Todas las páginas hablan como controlar los errores y crear páginas personalizadas. Pero ¿cómo lanzar un error y que la aplicación muestre nuestra flamante página de error?

La primera idea ha sido:
Response.StatusCode= 403;
Response.End();

Pero esto te lleva a la página de error de IIS, no de asp.net. Si no forzamos en fin de Response, nuestra página cargará normalmente. De poco nos sirve poner el StatusCode.

Solución:
Desde el código desde donde queramos lanzar la prohibición:
throw new HttpException(403, 'Mensaje de error personalizado');
Es decir, lanzar una excepción, pero basada en HttpException y no en Exception.

Ahora sí. Solo hace falta capturar los errores en el global.asax, en el evento Application_Error
protected void Application_Error(object sender, EventArgs e) {
Exception ex = Server.GetLastError();
if (ex is HttpException) {
HttpException httpex;
httpex = ex as HttpException;
switch (httpex.GetHttpCode()) {
case 401:
//Lo que sea
break;
case 403:
//Lo que sea
break;
}
} else
//es una excepción genérica
}

¿Qué más hay que hacer para que todo esto funcione?
Pues decirle a asp.net dónde está y como se se llama nuestra página (o páginas) de error personalizada. Podríamos tener una página por código de error.
Esta es una configuración básica que funciona muy bien:
<customerrors mode="RemoteOnly">
defaultredirect="~/Errors.aspx"
</customerrors>

Más info sobre customerrors.

Comentarios

Miguel ha dicho que…
una forma más refinada de ésto se puede encontrar en: http://www.4guysfromrolla.com/ScottMitchell.shtml.
Aquí se utiliza un módulo, que basta con insertarlo en el web.config para tener la gestión de errores activada.