ASP.NET MVC自定义异常过滤器以强制返回完整视图,而不是部分视图。

6
我有一个自定义异常过滤器,我通过在类上添加[CustomExceptionFilter]属性来调用它。它的工作方式符合我的期望,但是如果操作方法通过ajax请求返回部分视图,那么异常(基本上是重定向到未授权页面)将使用该页面加载部分视图。是否有一种方法可以强制重新加载“父”URL?
以下是自定义异常过滤器的代码:
public class CustomExceptionFilter : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        if (filterContext.Exception.GetType() == typeof(CustomSecurityException))
        {
            filterContext.ExceptionHandled = true;
            RequestContext rc = new RequestContext(filterContext.HttpContext, filterContext.RouteData);
            string url = RouteTable.Routes.GetVirtualPath(rc, new RouteValueDictionary(new { Controller = "NoAccess", action = "Index", message = filterContext.Exception.Message })).VirtualPath;
            filterContext.HttpContext.Response.Redirect(url, true);
        }
    }
}
8个回答

2

这是正确的答案,因为当出现ajax错误时,既不会触发自定义异常也不会触发控制器代码。 - Stuart Dobson

1

我在表单标签中使用了OnFailure处理程序。

<form id="AJAXForm" method="post" action=""
   onsubmit="Sys.Mvc.AsyncForm.handleSubmit(this, new Sys.UI.DomEvent(event),
   { insertionMode: Sys.Mvc.InsertionMode.replace, httpMethod: 'POST', 
   updateTargetId: 'myPartialPage', onSuccess: Function.createDelegate(this, ajaxFormSucced),
   onFailure: Function.createDelegate(this, ajaxFormFailure) });" >

... function ajaxFormSucced(){ // 成功时的代码 } function ajaxFormFailure(){ // 失败时的代码 }


1

我建议让异常向上冒泡到客户端,并像Maxwell建议的那样处理它。

在我们之前的项目中,我们使用了一个特定的ActionFilter来处理ajax错误(从Suteki Shop借鉴而来)。请注意,响应状态为500(内部服务器错误)。响应中需要一个错误状态,以便在JQuery.ajax()调用中调用Error()委托。

 public class HandleErrorWithAjaxAttribute : HandleErrorAttribute
    {
        public HandleErrorWithAjaxAttribute()
        {
            ShowStackTraceIfNotDebug = true;
        }

        public bool ShowStackTraceIfNotDebug { get; set; }

        public override void OnException(ExceptionContext filterContext)
        {
            if (filterContext.HttpContext.Request.IsAjaxRequest())
            {
                string content = ShowStackTraceIfNotDebug ||
                                 filterContext.HttpContext.IsDebuggingEnabled
                                     ?
                                         filterContext.Exception.StackTrace
                                     :
                                         string.Empty;
                filterContext.Result = new ContentResult
                                           {
                                               ContentType = MediaTypeNames.Text.Plain,
                                               Content = content
                                           };
                filterContext.HttpContext.Response.Status =
                    "500 " + filterContext.Exception.Message
                                 .Replace("\r", " ")
                                 .Replace("\n", " ");
                filterContext.ExceptionHandled = true;
                filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
            }
            else
            {
                base.OnException(filterContext);
            }
        }
    }

0

您可以验证请求是否为ajax请求。例如,您可以执行以下操作...

if (!filterContext.HttpContext.Request.IsAjaxRequest()){
    //Return a ViewResult
    //filterContext.ExceptionHandled = true;
    //filterContext.Result = new ViewResult { ViewName = "Error" ... };
}
else{
    //An ajax request. 
    //return a partial view
}

然而,正如Maxwell所说,如果它是一个ajax请求,你可以让异常冒泡并在客户端处理错误。您可以全局设置一种处理ajax请求异常的方式,就像这里描述的那样。


0

你尝试清除响应了吗?控制器可能仍在设置响应内容。

filterContext.HttpContext.Response.Clear()
filterContext.Result = new JsonResult { Data = new { Message = message } };
filterContext.HttpContext.Response.StatusCode = 500;
filterContext.ExceptionHandled = true;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;

0
正如Maxwell所说,可以在客户端上处理,使用类似这样的东西。
function handleError(ajaxContext) {
    // Load parent
}

@using (Ajax.BeginForm("Index", "Home", new AjaxOptions
{         
    UpdateTargetId = "MyDiv",
    OnFailure = "handleError"
}))

你必须确保在控制器ActionResult代码中包含以下代码,以便触发ajax错误。
HttpContext.Response.StatusCode = 401;

0

这个链接帮助了我:使用jQuery通过Ajax向控制器提交ASP.NET MVC异常处理

最后,当测试JavaScript函数时,请从第一行开始使用警报。您的函数中的任何JavaScript错误都可能在执行过程中停止函数,而浏览器不会提供JavaScript错误反馈(取决于您的设置)。


0

这个链接会对你有所帮助。

只需添加.IsAjaxRequest扩展方法并向浏览器返回403状态码,jquery ajaxError将处理它并重定向到登录页面。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接