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");