Respuesta rápida / TL; DR
Para la gente perezosa por ahí:
Install-Package MagicalUnicornMvcErrorToolkit -Version 1.0
Luego elimine esta línea de global.asax
GlobalFilters.Filters.Add(new HandleErrorAttribute());
Y esto es solo para IIS7 + e IIS Express.
Si estás usando Cassini ... bueno ... um ... er ... incómodo ...
Respuesta larga y explicada
Sé que esto ha sido respondido. Pero la respuesta es REALMENTE SIMPLE (aplausos para David Fowler y Damian Edwards por responder realmente esto).
No hay necesidad de hacer nada personalizado .
Para ASP.NET MVC3
, todos los pedazos están ahí.
Paso 1 -> Actualiza tu web.config en DOS lugares.
<system.web>
<customErrors mode="On" defaultRedirect="/ServerError">
<error statusCode="404" redirect="/NotFound" />
</customErrors>
y
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="404" subStatusCode="-1" />
<error statusCode="404" path="/NotFound" responseMode="ExecuteURL" />
<remove statusCode="500" subStatusCode="-1" />
<error statusCode="500" path="/ServerError" responseMode="ExecuteURL" />
</httpErrors>
...
<system.webServer>
...
</system.web>
Ahora tome nota de las RUTAS que he decidido utilizar. Puedes usar cualquier cosa, pero mis rutas son
/NotFound
<- para un 404 no encontrado, página de error.
/ServerError
<- para cualquier otro error, incluya los errores que suceden en mi código. este es un error interno del servidor 500
¿Ves cómo la primera sección <system.web>
solo tiene una entrada personalizada? La statusCode="404"
entrada? Solo he enumerado un código de estado porque todos los demás errores, incluido el 500 Server Error
(es decir, esos molestos errores que ocurren cuando su código tiene un error y bloquea la solicitud del usuario) ... todos los otros errores son manejados por la configuración defaultRedirect="/ServerError"
... que dice , si no se encuentra una página 404, vaya a la ruta /ServerError
.
Okay. eso está fuera del camino ... ahora a mis rutas enumeradas englobal.asax
Paso 2: crear las rutas en Global.asax
Aquí está mi sección de ruta completa ...
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.IgnoreRoute("{*favicon}", new {favicon = @"(.*/)?favicon.ico(/.*)?"});
routes.MapRoute(
"Error - 404",
"NotFound",
new { controller = "Error", action = "NotFound" }
);
routes.MapRoute(
"Error - 500",
"ServerError",
new { controller = "Error", action = "ServerError"}
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new {controller = "Home", action = "Index", id = UrlParameter.Optional}
);
}
Eso enumera dos rutas de ignorar -> axd's
y favicons
(¡ooo! Bonus ignora la ruta, ¡para ti!) Luego (y el pedido es IMPERATIVO AQUÍ), tengo mis dos rutas explícitas de manejo de errores ... seguidas de cualquier otra ruta. En este caso, el predeterminado. Por supuesto, tengo más, pero eso es especial para mi sitio web. Solo asegúrese de que las rutas de error estén en la parte superior de la lista. El orden es imperativo .
Finalmente, mientras estamos dentro de nuestro global.asax
archivo, NO registramos globalmente el atributo HandleError. No, no, no señor. Nadda No Nien Negativo. Noooooooooo ...
Eliminar esta línea de global.asax
GlobalFilters.Filters.Add(new HandleErrorAttribute());
Paso 3: crea el controlador con los métodos de acción
Ahora ... agregamos un controlador con dos métodos de acción ...
public class ErrorController : Controller
{
public ActionResult NotFound()
{
Response.StatusCode = (int)HttpStatusCode.NotFound;
return View();
}
public ActionResult ServerError()
{
Response.StatusCode = (int)HttpStatusCode.InternalServerError;
// Todo: Pass the exception into the view model, which you can make.
// That's an exercise, dear reader, for -you-.
// In case u want to pass it to the view, if you're admin, etc.
// if (User.IsAdmin) // <-- I just made that up :) U get the idea...
// {
// var exception = Server.GetLastError();
// // etc..
// }
return View();
}
// Shhh .. secret test method .. ooOOooOooOOOooohhhhhhhh
public ActionResult ThrowError()
{
throw new NotImplementedException("Pew ^ Pew");
}
}
Ok, veamos esto. En primer lugar, NO hay [HandleError]
atributo aquí. ¿Por qué? Debido a que el ASP.NET
marco integrado ya está manejando errores Y hemos especificado toda la mierda que debemos hacer para manejar un error :) ¡Está en este método!
A continuación, tengo los dos métodos de acción. Nada duro allí. Si desea mostrar alguna información de excepción, puede usarla Server.GetLastError()
para obtener esa información.
Bonificación WTF: Sí, hice un tercer método de acción, para probar el manejo de errores.
Paso 4: crea las vistas
Y finalmente, crea dos vistas. Póngalos en el punto de vista normal, para este controlador.
Comentarios adicionales
- No necesitas un
Application_Error(object sender, EventArgs e)
- Todos los pasos anteriores funcionan 100% perfectamente con Elmah . Elmah fraking wroxs!
Y eso, mis amigos, debería ser.
¡Ahora, felicidades por leer tanto y tener un Unicornio como premio!