6

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

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

4

4 回答 4

4

MVC 附带的 HandleErrorAttribute 是一个非常基本的 IExceptionFilter

你有几个选择来实现我认为你想要的。

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

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

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

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

于 2008-10-13T12:41:57.307 回答
2

Leppi,如果要发送到 Action Result,可以定义 Action 和 Controller 以在错误时重定向。这是一个很好的例子,但我个人不喜欢不使用自定义页面或 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
于 2009-04-16T14:40:07.977 回答
1

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

于 2008-10-13T12:34:43.873 回答
0

我正在做的(这可能是也可能不是一个好习惯)是这样的:

发生错误时:

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

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

于 2008-10-13T13:26:55.233 回答