错误页面总是在部分视图中加载

Error page always loads inside partial view

我一直在努力解决这个问题,但我似乎找不到适合我的解决方案。

我通过重写我的 BaseController class 中的 OnException 方法来处理所有错误,所有其他控制器都继承该方法。

protected override void OnException(ExceptionContext filterContext)
        {
            filterContext.ExceptionHandled = true;
            var rd = new RouteData
            {
                Values = { ["controller"] = "Error", ["action"] = "Index" },
                DataTokens = { }
            };
            var error = $@"Error: {filterContext.Exception.Message} in {filterContext.HttpContext.Request.FilePath}
                           Details: 
                           {filterContext.Exception.StackTrace}";

            _logger = LogManager.GetLogger(GetType());
            _logger.Error(error + Environment.NewLine + "Temp Id: " + AppSession.TempId);

            IController c = new ErrorController();
            c.Execute(new RequestContext(new HttpContextWrapper(System.Web.HttpContext.Current), rd));
        }

我的错误控制器非常简单:

public ActionResult Index()
        {
            ViewBag.Error = "Oops.. Something went wrong";
            return View("Error");
        }

有效,错误页面显示,但它总是在部分视图容器内加载,即引发错误的部分视图。相反,我想单独重定向到错误页面。

我试过以这种方式使用和处理错误,但它的行为方式完全相同。我也尝试过处理 Global.asax Application_Error 方法中的错误,我知道这不会有任何区别,但我想要 无论如何都要尝试..

我的猜测是因为局部视图是通过 $.get 调用加载的,它以某种方式将响应包装在局部视图应该加载的相同 div/container 中。

如有任何帮助,我们将不胜感激。如果您需要更多信息,请告诉我。

我也尝试在 SO 上查找类似的情况,但我发现 post 没有一个好的解决方案...

提前致谢。

你应该做的是,如果错误发生在 ajax 调用中,你应该发送一个 json 响应,其中包含 属性 指示哪个 url 重定向到。如果不是ajax请求,可以发送正常的重定向结果。

像这样

protected override void OnException(ExceptionContext filterContext)
{
    //your existing code to log errors here

    filterContext.ExceptionHandled = true;
    if (filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
    {
        var targetUrl = UrlHelper.GenerateUrl("Default", "Index", "Error", 
              new RouteValueDictionary(), RouteTable.Routes, Request.RequestContext, false);

        filterContext.Result = new JsonResult
        {
            JsonRequestBehavior = JsonRequestBehavior.AllowGet,
            Data = new { Error = true, Message = filterContext.Exception.Message,
                                                                   RedirectUrl= targetUrl }
        };
        filterContext.HttpContext.Response.StatusCode = 500;

        filterContext.ExceptionHandled = true;
    }
    else
    {
        filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary 
                                          {{"controller", "Error"}, {"action", "Index"}});
    }
}

现在您可以监听 .ajaxError() 事件,只要 ajax 请求完成但出现错误,该事件就会被触发。获取 RedirectUrl 值并根据需要重定向。您还可以考虑向用户显示一条有意义的消息(即使在模态对话框的部分视图中)这样用户就不会被盲目重定向搞糊涂了!

$(function () {

        $(document).ajaxError(function (event, request, settings) {           
            console.log('ajax request', request.responseText);
            var d = JSON.parse(request.responseText);
            alert("Ajax error:"+d.Message);
            window.location.href = d.RedirectUrl;
        });
});