2010-02-12 3 views
6

У меня есть настраиваемый фильтр исключительных ситуаций, который я вызываю в силу добавления атрибута [CustomExceptionFilter] в мой класс. Он работает так, как мне бы хотелось, но если метод действия возвращает частичное представление (через запрос ajax), исключение (которое в основном является перенаправлением на неавторизованную страницу), загружает частичный вид с помощью этого стр. Есть ли способ заставить его перезагрузить «родительский» URL-адрес?asp.net mvc custom exception filter для принудительного возврата полного представления, а не частичного

Вот код для пользовательского исключения фильтра

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

ответ

2

Это то, что вам нужно работать в браузере. Попробуйте обработать error() on jQuery.ajax() call, например (и, очевидно, не возвращать перенаправление ..).

+0

Это правильный ответ, потому что, когда есть ошибка ajax, ни пользовательское исключение, ни код контроллера не попадают. – stuartdotnet

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 
} 

Однако, как Максвелл сказал, что вы могли бы позволить Exeption пузырь, если это запрос Ajax и обработать ошибку на клиенте. Вы можете настроить глобальный способ обработки исключений в запросах ajax, как описано here

1

Я предлагаю разрешить исключение пузырьку до клиента и обрабатывать его, как предложил Максвелл.

В нашем предыдущем проекте мы использовали специальный actionfilter для обработки ошибок ajax (заимствованный от Suteki Shop). Обратите внимание, что статус ответа 500 (внутренняя ошибка сервера). Для ответа на запрос для вызова делегата Error() для вызова JQuery.ajax() требуется статус ошибки.

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

Вы попробовали очистить отклик? Контроллер все еще может настраивать содержимое ответа.

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

... функция ajaxFormSucced() {// Код для успеха } функция ajaxFormFailure() {// Код для отказа }

0

Эта ссылка помогла мне Handling ASP.NET MVC exceptions when posting to the controller via Ajax using jQuery

Наконец, при тестировании функции javascript functio n, начните с предупреждения в первой строке. Любые ошибки javascript в вашей функции, вероятно, остановят функцию в середине исполнения без обратной связи с JavaScript через браузер (в зависимости от вашей настройки).

0

This поможет вам.

Просто добавьте.Метод расширения IsAjaxRequest и возврата 403 код статуса в браузере, JQuery ajaxError будет обрабатывать это перенаправление на страницу входа в

0

Как говорит Максвелл, ручка на клиенте, используя что-то вроде этого

function handleError(ajaxContext) { 
    // Load parent 
} 

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

Что вы должны сделать, хотя это убедитесь, что в контроллере код ActionResult для NoAccess содержит следующий код, так что вы запускаете свою ошибку ajax.

HttpContext.Response.StatusCode = 401;