我的基本控制器中有一个可以处理我无法捕获的错误的捕获.它大致如下:
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); }
现在,如果控制器中发生错误,这可以很好地工作.问题是,如果错误发生在aspx页面呈现期间(例如,在HtmlHelper方法中),则会在发生错误的页面上呈现整个错误视图.这意味着整个错误页面(MasterPage和all)都会在错误的页面中呈现.不完全是预期的行为.
我已经尝试将View更改为RedirectToAction,但这不起作用,因为每个控制器都不存在路由(Home / Error,Configuration / Error等).
解决方法
您需要一种方法来跟踪页面所处的状态,以便您可以区分是否正在执行操作 – 在这种情况下您要替换结果 – 或执行结果 – 在这种情况下您要丢弃响应的内容并为错误执行新的ViewResult.在基本控制器中保留标志将是处理此问题的一种方法.您也可以根据异常类型判断.我不确定会有多可靠.
一旦你弄清楚你可以做的状态:
var view = View("Error",data ); if (executingResult) { filterContext.HttpContext.Response.ClearContent(); view.ExecuteResult(); } else { filterContext.Result = view; base.OnException( filterContext ); }
评论:一般来说,我不主张这样做.我认为您的控制器操作应该向View保证它需要的所有数据都存在,或者您的View应该以防御方式编写,以确保不会发生异常(特别是NullReferenceExceptions).