Saltar al contenido

ASP.NET MVC Manejo de errores personalizado Application_Error Global.asax?

No olvides que en las ciencias cualquier problema casi siempre tiene más de una resoluciones, pero aquí enseñamos lo mejor y más eficiente.

Solución:

En lugar de crear una nueva ruta para eso, puede simplemente redirigir a su controlador / acción y pasar la información a través de la cadena de consulta. Por ejemplo:

protected void Application_Error(object sender, EventArgs e) {
  Exception exception = Server.GetLastError();
  Response.Clear();

  HttpException httpException = exception as HttpException;

  if (httpException != null) 
    string action;

    switch (httpException.GetHttpCode()) 
      case 404:
        // page not found
        action = "HttpError404";
        break;
      case 500:
        // server error
        action = "HttpError500";
        break;
      default:
        action = "General";
        break;
      

      // clear error on server
      Server.ClearError();

      Response.Redirect(String.Format("~/Error/0/?message=1", action, exception.Message));
    

Entonces tu controlador recibirá lo que quieras:

// GET: /Error/HttpError404
public ActionResult HttpError404(string message) 
   return View("SomeView", message);

Hay algunas compensaciones con su enfoque. Tenga mucho cuidado con los bucles en este tipo de manejo de errores. Otra cosa es que, dado que está pasando por la canalización de asp.net para manejar un 404, creará un objeto de sesión para todos esos hits. Esto puede ser un problema (rendimiento) para sistemas muy utilizados.

Para responder a la pregunta inicial “¿cómo pasar correctamente los datos de ruta al controlador de errores?”:

IController errorController = new ErrorController();
errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));

Luego, en su clase ErrorController, implemente una función como esta:

[AcceptVerbs(HttpVerbs.Get)]
public ViewResult Error(Exception exception)

    return View("Error", exception);

Esto empuja la excepción a la Vista. La página de visualización debe declararse de la siguiente manera:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %>

Y el código para mostrar el error:

<% if(Model != null)  %>  

Detailed error:
<%= Helpers.General.GetErrorMessage((Exception)Model, false) %>

<% %>

Aquí está la función que recopila todos los mensajes de excepción del árbol de excepciones:

    public static string GetErrorMessage(Exception ex, bool includeStackTrace)
    
        StringBuilder msg = new StringBuilder();
        BuildErrorMessage(ex, ref msg);
        if (includeStackTrace)
        
            msg.Append("n");
            msg.Append(ex.StackTrace);
        
        return msg.ToString();
    

    private static void BuildErrorMessage(Exception ex, ref StringBuilder msg)
    
        if (ex != null)
        
            msg.Append(ex.Message);
            msg.Append("n");
            if (ex.InnerException != null)
            
                BuildErrorMessage(ex.InnerException, ref msg);
            
        
    

Encontré una solución para el problema de ajax señalado por Lion_cl.

global.asax:

protected void Application_Error()
               
        if (HttpContext.Current.Request.IsAjaxRequest())
        
            HttpContext ctx = HttpContext.Current;
            ctx.Response.Clear();
            RequestContext rc = ((MvcHandler)ctx.CurrentHandler).RequestContext;
            rc.RouteData.Values["action"] = "AjaxGlobalError";

            // TODO: distinguish between 404 and other errors if needed
            rc.RouteData.Values["newActionName"] = "WrongRequest";

            rc.RouteData.Values["controller"] = "ErrorPages";
            IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
            IController controller = factory.CreateController(rc, "ErrorPages");
            controller.Execute(rc);
            ctx.Server.ClearError();
        
    

ErrorPagesController

public ActionResult AjaxGlobalError(string newActionName)
    
        return new AjaxRedirectResult(Url.Action(newActionName), this.ControllerContext);
    

AjaxRedirectResult

public class AjaxRedirectResult : RedirectResult

    public AjaxRedirectResult(string url, ControllerContext controllerContext)
        : base(url)
    
        ExecuteResult(controllerContext);
    

    public override void ExecuteResult(ControllerContext context)
    
        if (context.RequestContext.HttpContext.Request.IsAjaxRequest())
        
            JavaScriptResult result = new JavaScriptResult()
            
                Script = "tryhistory.pushState(null,null,window.location.href);catch(err)window.location.replace('" + UrlHelper.GenerateContentUrl(this.Url, context.HttpContext) + "');"
            ;

            result.ExecuteResult(context);
        
        else
        
            base.ExecuteResult(context);
        
    

AjaxRequestExtension

public static class AjaxRequestExtension

    public static bool IsAjaxRequest(this HttpRequest request)
    
        return (request.Headers["X-Requested-With"] != null && request.Headers["X-Requested-With"] == "XMLHttpRequest");
    

Reseñas y valoraciones

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *