2009-09-23 57 views
14

Quiero usar Application_Error con mi proyecto MVC, pero no puedo hacerlo funcionar. Añado lo siguiente a mi archivo Global.asax: (. La sesión es sólo para pruebas Im que va a utilizar una base de datos para registrar el error, si consigo que esto funcione.)¿Cómo uso Application_Error en ASP.NET MVC?

protected void Application_Error(object sender, EventArgs e) 
    { 
     Exception objErr = Server.GetLastError().GetBaseException(); 
     Session["Test"] = "Message:" + objErr.Message.ToString(); 
    } 

entonces trato de lanzar una excepción de mi HomeController y mi Home/Index View, pero solo activa Debug.

public ActionResult Index() 
    { 
     ViewData["Message"] = "Welcome to ASP.NET MVC!"; 
     throw (new Exception()); 
     return View(); 
    } 

En mi archivo Webconfig fijo una página defaulterror pero no redirige a la vista:

<customErrors defaultRedirect="Home/Error"> 
     <error statusCode="403" redirect="NoAccess.htm" /> 
     <error statusCode="404" redirect="FileNotFound.htm" /> 
    </customErrors> 

Respuesta

14

En primer lugar, recuerde que el manejo de errores globales debería ser un último recurso, y las clases de controlador tienen un método de error específico para los errores;

protected virtual bool OnError(string actionName, 
    System.Reflection.MethodInfo methodInfo, Exception exception) 

Dentro de esto puede redirigir a la vista estándar de error compartido;

protected override bool OnError(string actionName, 
    System.Reflection.MethodInfo methodInfo, Exception exception) 
{ 
    RenderView("Error", exception); 
    return false; 
} 

El problema que tiene en el error de aplicación mundial es que no tiene ningún concepto de puntos de vista o controladores, por lo que si desea redirigir allí entonces usted debe utilizar una URL conocida

protected void Application_Error(object sender, EventArgs e) 
{ 
    Exception exception = Server.GetLastError(); 
    System.Diagnostics.Debug.WriteLine(exception); 
    Response.Redirect("/Home/Error"); 
} 

pero no necesita hacer esto. Si configura la página de error predeterminada en la web.config, entonces no es necesario que redirigen

<customErrors defaultRedirect="Home/Error" /> 

Sin embargo, a menos que haya añadido una vista de error al controlador principal que no existe, por lo que añadir lo siguiente al controlador de casa

public ActionResult Error() 
{ 
    return View(); 
} 

Luego (si es sensato) pondría el código de manejo de errores en el método Error(), ya que es donde terminarán todos los errores no administrados.

public ActionResult Error() 
{ 
    Exception exception = Server.GetLastError(); 
    System.Diagnostics.Debug.WriteLine(exception); 
    return View(); 
} 

Y, por último recuerda que por defecto no ve errores personalizados si se está conectando a localhost! Entonces necesita cambiar ese comportamiento

<customErrors mode="On" defaultRedirect="/Home/Error" /> 
+1

Tengo un problema con su solución. CustomErrors redirige directamente a la vista de Inicio/Errores sin activar el controlador. No sabía lo que era posible, pero cuando pongo un punto de depuración en el método de Error Action, la depuración nunca es llamada. La vista de error solo se muestra en la pantalla, pero la url sigue siendo la misma que la que desencadenó el error. Por ejemplo, si desencadenar un error en/Inicio/Trabajo obtendré la vista de error, pero la URL todavía está/Inicio/Trabajo – Poku

+18

Hola @blowdart: mensaje cortesía de un nuevo usuario que no puede comentar: Esta respuesta es rotunda incorrecto. El problema es que llamar a Server.GetLastError() desde la clase de controlador no funciona si usa web.config para redirigir a una acción de controlador predeterminada. ASP inicia una nueva solicitud HTTP al controlador de errores, que borra las variables del Servidor, perdiendo la información de la excepción. –

+3

mala respuesta ..... aquí hay un buen artículo sobre por qué debería usar tanto http://www.prideparrot.com/blog/archive/2012/5/exception_handling_in_asp_net_mvc –

1
  • ¿Tiene un Sesión creó en primer lugar? Si el error se desencadena desde un IHttpHandler no marcado con IRequiresSessionState, entonces el acceso a Session fallará.
  • ¿Qué estás haciendo con Session["Test"]? ¿Estás seguro de que tu código no funciona? Puede probar File.Open y simplemente enviar un texto (por ejemplo, la hora actual) a C:\my-log.txt, que es un poco más probable que tenga éxito que usando Session.
  • GetBaseException no es útil en este caso (ni en general para el registro) por lo que puedo decir.
  • Message es del tipo string - no es necesario llamar al .ToString(). En general, recomiendo encarecidamente evitandoToString() donde sea posible: si lo está usando porque no está seguro del tipo de objeto, debería ser una bandera roja; hacer un recorrido final alrededor del sistema de tipo puede ocultar errores sutiles (por ejemplo, DBNull.Value.ToString() == ""). Para GUI, los tipos integrados proporcionan una sobrecarga de .ToString(IFormatProvider) que es culturalmente sensible y evita problemas de portabilidad. Como esa sobrecarga tampoco está presente en object, también es una medida de seguridad para evitar las llamadas .ToString de tipo muy débil.
Cuestiones relacionadas