错误页面始终在局部视图中加载

时间:2016-09-08 16:01:07

标签: javascript ajax asp.net-mvc error-handling asp.net-ajax

我一直在努力解决这个问题很长一段时间,但我似乎无法找到适合我的解决方案。

我通过覆盖我的BaseController类中的 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 /容器中。

非常感谢任何帮助。如果您需要更多信息,请告诉我。

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

提前致谢。

1 个答案:

答案 0 :(得分:2)

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

像这样的东西

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;
        });
});