使用ErrorController而不是直接视图处理错误

时间:2008-10-13 12:32:03

标签: c# asp.net-mvc error-handling error-logging

我正试图了解MVC中的错误处理。 我正在寻找的是一种集中的方式来捕获错误,记录它们,如果可能的话解决它们,如果nessecary采取其他行动并最终向用户显示正确的视图。

我想我可以使用[HandleError]过滤器,但我没有看到任何方法将它路由到Controller / Action。我看到的唯一选择是将其直接指向视图。

4 个答案:

答案 0 :(得分:4)

MVC附带的

HandleErrorAttribute是一个非常基本的IExceptionFilter。

你有几个选择来实现我想你想要的东西。

你可以在动作/控制器上使用[HandleError(Type = typeof(MyException),View =“ErrorView”)]或实现你自己的

HandleErrorAttribute并不复杂。我认为MS建议您复制此代码并进行修改以满足您的要求。

OnException覆盖使您可以通过ExceptionContext访问您可能需要的所有信息 - 控制器,操作,路由数据等。

请记住设置ExceptionHandled。然后你可以将filterContext.Result设置为一个新的RedirectToAction实例,该实例重定向到你的ErrorController和action - 显然你可以用属性公开特定的控制器和动作。

答案 1 :(得分:2)

Leppi,如果您想发送到Action Result,您可以定义Action and Controller to Redirect on Error。这是一个很好的例子,但我不喜欢不使用自定义页面或http代码来代码

这是我的IExtenptionFilter的示例。我的基本控制器有一个默认的IExceptionFilter来处理所有没有控制的错误。

[SuppressMessage("Microsoft.Performance", "CA1813:AvoidUnsealedAttributes",
    Justification = "This attribute is AllowMultiple = true and users might want to override behavior.")]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class GenericExceptionHandlerFilter : ActionFilterAttribute, IExceptionFilter
{

    public Type ExceptionType { get; set;}
    public string RedirectToAction { get; set;}
    public string RedirectToController { get; set;}

    protected bool ApplyFilter(ExceptionContext filterContext)
    {
        Type lExceptionType = filterContext.Exception.GetType();
        return (ExceptionType == null ||
                lExceptionType.Equals(ExceptionType));
    }


    #region IExceptionFilter Members
    public void OnException(ExceptionContext filterContext)
    {

        if (ApplyFilter(filterContext))
        {
            IbfControllerLogger.Log(filterContext.Exception);

            filterContext.ExceptionHandled = true;

            #region Calculate Action Controller Error
            RouteValueDictionary lRoutes = new RouteValueDictionary(new
                {
                    action = RedirectToAction,
                    controller = String.IsNullOrEmpty(RedirectToController) ? (string)filterContext.RouteData.Values["controller"] : RedirectToController
                });
            UrlReWriterUtils.UrlReWriter(filterContext.Controller.ViewData, lRoutes);
            #endregion

            filterContext.Controller.TempData[TempDataName.C_TEMPDATA_EXCEPTIONERROR] = filterContext.Exception;
            filterContext.Result = new RedirectToRouteResult(lRoutes);
        }
    }
    #endregion

答案 2 :(得分:1)

为什么不创建自己的ActionResult派生的ErrorResult?

答案 3 :(得分:0)

我正在做的事情(这可能是也可能不是一种好的做法)是:

发生错误时:

  • 如果我预料到它可以处理它,我会(用ELMAH记录)
  • 如果我期望它并且无法处理它,我将它记录到ELMAH并返回一个ViewResult,这是我的错误页面
    • 包括错误描述,标准消息和回到我正在做的事情的链接
  • 如果我没想到它,我在基本控制器类中覆盖OnError会执行上一步
  • ELMAH和请求黄屏
  • 会自动记录无法处理的所有其他错误

我的大多数通用错误处理都在我的所有控制器的基类中。唯一的问题是我必须在基类中手动设置控制器和操作值,以便它可以在错误页面中为重定向生成ActionLink。