Estoy desarrollando un sitio web base MVC3 y estoy buscando una solución para manejar errores y renderizar vistas personalizadas para cada tipo de error. Imagine que tengo un controlador "Error" donde su acción principal es "Índice" (página de error genérico) y este controlador tendrá un par de acciones más para los errores que pueden aparecer al usuario como "Handle500" o "HandleActionNotFound".
Por lo tanto, cada error que pueda ocurrir en el sitio web puede ser manejado por este controlador "Error" (ejemplos: "Controlador" o "Acción" no encontrado, 500, 404, dbException, etc.).
Estoy usando el archivo Sitemap para definir las rutas del sitio web (y no la ruta).
Esta pregunta ya fue respondida, esta es una respuesta a Gweebz
Mi método final applicationiton_error es el siguiente:
protected void Application_Error() {
//while my project is running in debug mode
if (HttpContext.Current.IsDebuggingEnabled && WebConfigurationManager.AppSettings["EnableCustomErrorPage"].Equals("false"))
{
Log.Logger.Error("unhandled exception: ", Server.GetLastError());
}
else
{
try
{
var exception = Server.GetLastError();
Log.Logger.Error("unhandled exception: ", exception);
Response.Clear();
Server.ClearError();
var routeData = new RouteData();
routeData.Values["controller"] = "Errors";
routeData.Values["action"] = "General";
routeData.Values["exception"] = exception;
IController errorsController = new ErrorsController();
var rc = new RequestContext(new HttpContextWrapper(Context), routeData);
errorsController.Execute(rc);
}
catch (Exception e)
{
//if Error controller failed for same reason, we will display static HTML error page
Log.Logger.Fatal("failed to display error page, fallback to HTML error: ", e);
Response.TransmitFile("~/error.html");
}
}
}
fuente
Respuestas:
Aquí hay un ejemplo de cómo manejo los errores personalizados. Defino un
ErrorsController
con acciones que manejan diferentes errores HTTP:y luego me suscribo al
Application_Error
inGlobal.asax
e invoco este controlador:fuente
Execute
es un método definido en laIController
interfaz. Esto no puede ser protegido. Mire mi código con más cuidado:IController errorsController = new ErrorsController();
y observe el tipo deerrorsController
variable en la que estoy invocando elExecute
método. Es de tipo,IController
por lo que no hay absolutamente nada que le impida llamar a este método. Y, por cierto, tambiénExecute
estaba protegido en la clase Controller en MVC 3, por lo que no hay cambios a este respecto.Response.ContentType = "text/html";
Aquí hay más artículos Cómo crear páginas de error personalizadas con MVC http://kitsula.com/Article/MVC-Custom-Error-Pages .
fuente
También puede hacerlo en el archivo Web.Config. Aquí hay un ejemplo que funciona en IIS 7.5.
fuente
Veo que agregaste un valor de configuración
EnableCustomErrorPage
y también estás verificandoIsDebuggingEnabled
para determinar si debes ejecutar tu manejo de errores.Como ya hay una
<customErrors/>
configuración en ASP.NET (que está diseñada exactamente para este propósito), es más fácil decir:Luego, en la configuración que pondría,
<customErrors mode="RemoteOnly" />
que es segura de implementar de esa manera, y cuando necesite probar su página de error personalizada, la configurará para<customErrors mode="On" />
que pueda verificar que funciona.Tenga en cuenta que también debe verificar si
HttpContext.Current
es nulo porque una excepciónApplication_Start
seguirá siendo su método, aunque no habrá un contexto activo.fuente
Puede mostrar una página de error fácil de usar con el código de estado http correcto implementando el módulo de Manejo de excepciones amigable de Jeff Atwood con una ligera modificación del código de estado http. Funciona sin redireccionamientos. Aunque el código es de 2004 (!), Funciona bien con MVC. Se puede configurar completamente en su web.config, sin ningún cambio en el código fuente del proyecto MVC.
La modificación requerida para devolver el estado HTTP original en lugar de un
200
estado se describe en esta publicación relacionada del foro .Básicamente, en Handler.vb, puede agregar algo como:
fuente
Estoy usando MVC 4.5 y estaba teniendo problemas con la solución de Darin. Nota: la solución de Darin es excelente y la utilicé para encontrar mi solución. Aquí está mi solución modificada:
fuente