ASP.NET MVC中的通用基本控制器错误处理问题

7 error-handling asp.net-mvc

我的基本控制器中有一个处理我处理的错误.它大致如下:

protected override void OnException(ExceptionContext filterContext)
{
    // Bail if we can't do anything
    if (filterContext == null)
        return;

    // log
    var ex = filterContext.Exception ??
            new Exception("No further information exists.");
    LogException(ex);

    filterContext.ExceptionHandled = true;
    var data = new ErrorPresentation
        {
        ErrorMessage = HttpUtility.HtmlEncode(ex.Message),
        TheException = ex
        };
    filterContext.Result = View("Error", data);
    base.OnException(filterContext);
}
Run Code Online (Sandbox Code Playgroud)

现在,如果控制器中发生错误,这将非常有用.问题是,如果错误是aspx页面渲染期间(比如说,在一个方法的HtmlHelper),在整个错误观点被渲染,在地方发生错误的页面上.这意味着整个错误页面(MasterPage和all)都会在错误的页面中呈现.不完全是预期的行为.

我已经尝试将View更改为RedirectToAction,但这不起作用,因为每个控制器都不存在路由(Home/Error,Configuration/Error等).

如何才能使控制器中的错误和页面上的错误都能正常工作?

Bil*_*llB 12

这是一个老问题,但是对于任何拼命搜索的人来说,这个代码适用于我,任何地方的例外 - 控制器,动作或动作结果,即视图或视图调用的任何助手.(我是从史蒂夫桑德森的书中得到的,因为它归属于哪里):

protected override void OnException(ExceptionContext filterContext)
    {
        if (filterContext.ExceptionHandled)
            return;

        //Let the request know what went wrong
        filterContext.Controller.TempData["Exception"] = filterContext.Exception;

        //redirect to error handler
        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary(
            new { controller = "Exception", action = "HandleError" }));

        // Stop any other exception handlers from running
        filterContext.ExceptionHandled = true;

        // CLear out anything already in the response
        filterContext.HttpContext.Response.Clear();
    }
Run Code Online (Sandbox Code Playgroud)


tva*_*son 1

您需要一种方法来跟踪页面所处的状态,以便您可以区分是否正在执行操作(在这种情况下您想要替换结果)或正在执行结果(在这种情况下您想要丢弃)响应的内容并针对错误执行新的 ViewResult。在基本控制器中保留一个标志是处理此问题的一种方法。您也许还可以根据异常类型来判断。我不确定这有多可靠。

一旦确定了状态,您就可以执行以下操作:

 var view = View("Error", data );
 if (executingResult)
 {
     filterContext.HttpContext.Response.ClearContent();
     view.ExecuteResult();
 }
 else
 {
      filterContext.Result = view;
      base.OnException( filterContext );
 }
Run Code Online (Sandbox Code Playgroud)

评论:一般来说我不提倡这样做。我认为您的控制器操作应该向视图保证它需要的所有数据都在那里,或者您的视图应该进行防御性编写,以确保不会发生任何异常(特别是 NullReferenceExceptions)。