asp.net-mvc - practice - web api error handling
¿Cómo implementar un correcto manejo de errores HTTP en.NET MVC 2? (4)
Aquí hay una técnica que podrías usar. Defina un ErrorsController
que servirá las páginas de error:
public class ErrorsController : Controller
{
public ActionResult Http404()
{
Response.StatusCode = 404;
return Content("404", "text/plain");
}
public ActionResult Http500()
{
Response.StatusCode = 500;
return Content("500", "text/plain");
}
public ActionResult Http403()
{
Response.StatusCode = 403;
return Content("403", "text/plain");
}
}
y luego en Global.asax
podría suscribirse para el evento Application_Error
donde podría registrar la excepción y ejecutar la acción correspondiente de ErrorsController
:
protected void Application_Error(object sender, EventArgs e)
{
var app = (MvcApplication)sender;
var context = app.Context;
var ex = app.Server.GetLastError();
context.Response.Clear();
context.ClearError();
var httpException = ex as HttpException;
var routeData = new RouteData();
routeData.Values["controller"] = "errors";
routeData.Values["exception"] = ex;
routeData.Values["action"] = "http500";
if (httpException != null)
{
switch (httpException.GetHttpCode())
{
case 404:
routeData.Values["action"] = "http404";
break;
case 403:
routeData.Values["action"] = "http403";
break;
case 500:
routeData.Values["action"] = "http500";
break;
}
}
IController controller = new ErrorsController();
controller.Execute(new RequestContext(new HttpContextWrapper(context), routeData));
}
Y ahora todo lo que queda es comenzar a lanzar las excepciones adecuadas:
public class HomeController : Controller
{
public ActionResult Index()
{
throw new HttpException(404, "NotFound");
}
}
He estado luchando todo el día para implementar el manejo de errores en mi aplicación ASP.NET MVC 2. He visto una variedad de técnicas, pero ninguna funciona correctamente. Estoy usando MVC2 y .NET 4.0 (comencé el proyecto antes de que se lanzara MVC3, lo mejoraremos luego de que entreguemos nuestra versión inicial).
En este punto, estaré encantado de manejar adecuadamente los errores 404 y 500 - 403 (la autorización requerida) sería excelente, también, seguido por varias otras respuestas específicas. En este momento, o bien obtengo todos los 404, todos los 500, todos los 302 antes de los 404, o todos los 302 antes de los 500.
Estos son mis requisitos (que deberían ser muy similares a los requisitos básicos de HTTP):
Si no se encuentra un recurso, arroje un 404 y visualice una página específica de 404 con la URL solicitada. NO devuelva un código de respuesta intermedio como 302. Idealmente, conserve la URL solicitada, en lugar de mostrar una nueva URL como
/Error/NotFound
, pero si la última muestra, asegúrese de que no hayamos devuelto una respuesta de redireccionamiento para obtenerla.Si se produjo un error interno del servidor, arroje un 500 y muestre un error específico de 500 con alguna indicación de lo que salió mal. Nuevamente, no devuelva un código de respuesta intermedio, e idealmente no cambie la URL.
Esto es lo que consideraría un 404:
- Archivo estático no encontrado:
/Content/non-existent-dir/non-existent-file.txt
- Controlador no encontrado:
/non-existent-controller/Foo/666
- Controlador encontrado, pero Acción no encontrada:
/Home/non-existent-action/666
- Controlador y acción encontrados, pero la acción no puede encontrar el objeto solicitado:
/Home/Login/non-existent-id
Esto es lo que consideraría un 500:
- Publicar un valor incorrecto:
POST /User/New/new-user-name-too-long-for-db-column-constraint
- Problema no relacionado con los datos, como un punto final del servicio web que no responde
Algunos de estos problemas deben ser identificados por controladores o modelos específicos, y luego los controladores deben arrojar la HttpException apropiada. El resto debe manejarse de manera más genérica.
Para el caso n.º 404, traté de usar un ControllerFactory personalizado para lanzar un 404 si no se puede encontrar el controlador. Para el caso n.º 404, he intentado utilizar un controlador base personalizado para anular HandleUnknownAction
y lanzar un 404.
En ambos casos, obtengo un 302 antes del 404. Y nunca recibo 500 errores; si modifico Web.config para poner un error ortográfico en mi punto final del servicio web, aún obtengo un 302, luego un 404 que dice que no se puede encontrar el URL (controlador / acción) que utiliza el servicio web. También obtengo la URL solicitada como un param de cadena de consulta (no deseado): /Error/NotFound?aspxerrorpath=/Home/non-existent-action
Ambas técnicas provienen de http://www.niksmit.com/wp/?p=17 (Cómo obtener páginas de error normales 404 (Página no encontrada) usando ASP.Net MVC), apuntadas desde http://richarddingwall.name/2008/08/17/strategies-for-resource-based-404-errors-in-aspnet-mvc/
Si en Web.config tengo <customErrors mode="On" defaultRedirect="~/Error/Unknown" redirectMode="ResponseRedirect" />
, obtengo el código de respuesta apropiado, pero mi controlador de Error nunca recibe una llamada. Sacar el atributo redirectMode
me da las vistas de error MVC, pero con una 302 y una URL cambiadas, y siempre el mismo controlador ( Unknown
= 500; si lo cambio a NotFound
todo parece un 404).
Estas son algunas de las otras cosas que leí y traté de implementar:
- http://www.davidjuth.com/asp-net-mvc-error-handler.aspx
- http://sanjayuttam.com/wordpress/index.php/c-sharp/c-sharp-code-examples/error-handling-in-asp-net-mvc-1-part-2-of-2/
- http://blog.hebbink.com/post/2010/12/14/NET-custom-404-error-page-returns-302-for-http-status.aspx
- http://blog.dantup.com/2009/04/aspnet-mvc-handleerror-attribute-custom.html
- http://weblogs.asp.net/scottgu/archive/2008/07/14/asp-net-mvc-preview-4-release-part-1.aspx
.. junto con un montón de publicaciones de StackOverflow.
Me parece que este tipo de manejo de errores es bastante básico para las aplicaciones web, y el marco MVC debe tener valores predeterminados que lo hagan de la caja, y permita que las personas lo extiendan para funcionar de otra manera. Tal vez lo harán en una versión futura. Mientras tanto, ¿alguien puede darme detalles completos sobre cómo implementar respuestas HTTP adecuadas?
Esta es una pregunta muy antigua. pero pensé que valía la pena si le presentaba una manera mucho más limpia de manejar excepciones Http que vi en la querida "respuesta de Jesse Webb" .
La solución es usar el elemento httpErrors
de la sección system.webServer
:
<httpErrors errorMode="Custom" existingResponse="Replace">
<remove statusCode="404" subStatusCode="-1" />
<remove statusCode="500" subStatusCode="-1" />
<error statusCode="404" path="/Error/NotFound" responseMode="ExecuteURL" />
<error statusCode="500" path="/Error" responseMode="ExecuteURL" />
</httpErrors>
También puede registrar todas las excepciones de esta manera. "Lea la " respuesta de Jesse Webb " ".
Esto realmente se siente mucho más limpio y también funciona igual que cualquier otra solución (sin redirección).
Nota : Esto solo funciona en IIS 7 y más reciente. (Debido al elemento httpErrors
que se agregó recientemente.
Esto no responde a su pregunta, pero es importante tener en cuenta que el estado HTTP 500 indica que algo salió mal en el servidor, por lo que su ejemplo:
POST /User/New/new-user-name-too-long-for-db-column-constraint
No hay motivos válidos para lanzar un 500, es un problema de validación de datos y debe manejarse mediante anotaciones de datos MVC o un marco de validación jQuery o etc. Simplemente mostrando un mensaje de error al lado del TextBox diciendo "Nombre de usuario demasiado largo" es mucho mejor.
Para los errores HTTP 404 (sin redireccionamientos) eche un vistazo a la publicación de mi blog sobre el tema. Esto podría darte algunas buenas ideas:
http://hectorcorrea.com/blog/returning-http-404-in-asp-net-mvc/16