El proceso de manejo de errores personalizado en ASP.NET MVC (3 en este caso) parece estar increíblemente descuidado. He leído las diversas preguntas y respuestas aquí, en la web, páginas de ayuda para diversas herramientas (como Elmah), pero siento que he ido en un círculo completo y todavía no tengo la mejor solución. Con su ayuda, quizás podamos establecer un nuevo enfoque estándar para el manejo de errores. Me gustaría mantener las cosas simples y no sobre-diseñar esto.
Aquí están mis objetivos:
Para errores / excepciones del servidor:
- Mostrar información de depuración en dev
- Mostrar página de error amigable en producción
- Registrar errores y enviarlos por correo electrónico al administrador en producción
- Devolver 500 Código de estado HTTP
Para errores 404 no encontrados:
- Mostrar página de error amigable
- Registrar errores y enviarlos por correo electrónico al administrador en producción
- Devolver el código de estado HTTP 404
¿Hay alguna manera de cumplir estos objetivos con ASP.NET MVC?
Respuestas:
Compartiré la forma en que terminé haciendo esto, eso fue parte de la pregunta original.
Primero, los problemas que encontré:
Con customErrors activado (es decir, en producción), el
HandleError
atributo global traga excepciones y muestra su vista de error, pero no puede iniciar sesión con una herramienta adicional como elmah, ya que elmah nunca lo ve. Supongo que podría iniciar sesión en su vista, pero es una vista que parece incorrecta. El atributo global HandleError aparece nuevo en la plantilla de proyecto MVC 3 RTM Visual Studio.customErrors con URL para puntos finales MVC devuelve 302 códigos de estado. Existe la propiedad redirectmode, pero no puede hacer coincidir las URL de mvc en customErrors y usar el modo ResponseRewrite. ( https://stackoverflow.com/questions/781861/customerrors-does-not-work-when-setting-redirectmode-responserewrite/3770265#3770265 )
Evitar errores personalizados por completo y manejar todo lo personalizado en su aplicación conduce a una gran complejidad, IMO. (Me encantó esto: https://stackoverflow.com/questions/619895/how-can-i-properly-handle-404s-in-asp-net-mvc/2577095#2577095 , pero no fue adecuado para nuestro proyecto)
Mi solución
He sacado MVC de la ecuación por completo. He quitado
HandleErrorAttribute
el filtro global en global.asax y centrarse exclusivamente en la configuración customErrors, desplazándola a utilizar WebForm redirecciones y el cambio a redirectmode aResponseRewrite
fin de evitar los 302 códigos de respuesta HTTP.Luego, en el
NotFound.aspx
evento page_load, configure elResponse.StatusCode
404 y en Error.aspx configure el código 500.Resultados:
Los objetivos para ambos se han logrado con los registros de Elmah, la página de error amigable y el código de estado con una línea de código en los códigos subyacentes. No lo estamos haciendo a la "manera MVC" como lo hace la solución anterior, pero estoy de acuerdo con eso si son dos líneas de código.
fuente
Creo que MVC, ASP y su marco de registro / manejo de excepciones favorito pueden manejar sus objetivos bastante bien. ELMAH y Enterprise Library proporcionan un manejo y registro de excepciones fácil de usar, así que elige tu favorito ... No voy a entrar en los pros y los contras de cada uno aquí.
NOTA: no puede mostrar una página de error amigable Y devolver un HTTP 404 o 500 como sugiere su pregunta. Cuando devuelve una página de error amigable, el código HTTP devuelto a su navegador será 302. Esta es una redirección a la página de error amigable.
Páginas de error amigables
Parece que puede lograr sus objetivos con la buena configuración web.config que ha sido parte de ASP.net por algún tiempo. Usted menciona mostrar información de depuración cuando está en desarrollo y mostrar páginas amigables en producción. Puede usar la sección de errores personalizados de web.config para esto (Establecer CustomErrors = "Off" para mostrar información de depuración). Asumiré que está familiarizado con el atributo CustomErrors, si no, lea esto:
http://msdn.microsoft.com/en-us/library/h0hfz6fc.aspx
Si necesita una mayor granularidad de control sobre las vistas de error que muestra, utilice el atributo HandleError de MVC. De esta forma, puede elegir diferentes vistas de error para cada Acción / Controlador.
http://weblogs.asp.net/scottgu/archive/2008/07/14/asp-net-mvc-preview-4-release-part-1.aspx
Registro de excepciones
Parece que quiere responder a todas sus excepciones de la misma manera ('Registrar errores y enviarlos por correo electrónico al administrador en producción'). Si este es el caso, su opción más simple es agregar código a
Application_Error (remitente del objeto, EventArgs e)
en su global.asax. Aquí es donde puede pasar a su marco de registro elegido.
Si desea más control sobre su registro / manejo de excepciones, entonces puede subclasificar HandleErrorAttribute y anular
Este es otro lugar donde puede pasar a su marco de registro elegido.
https://stackoverflow.com/questions/183316/asp-net-mvc-handleerror
Esto le da más control que la técnica Application_Error mencionada anteriormente.
En general, MVC le brinda una gran granularidad de control sobre cómo manejar los errores. Si no necesita este control, puede recurrir a las formas ASP.net de hacer cosas como definir páginas de error en su web.config.
fuente