2010-02-12 20 views
6

Tengo un filtro de excepción personalizado que estoy llamando en virtud de agregar un atributo [CustomExceptionFilter] a mi clase. Funciona como me gustaría, sin embargo, si el método de acción devuelve una vista parcial (a través de una solicitud ajax), la excepción (que básicamente es un redireccionamiento a una página no autorizada), está cargando la vista parcial con ese página. ¿Hay alguna manera en que pueda obligarlo a volver a cargar la URL 'principal'?asp.net mvc filtro de excepción personalizado para forzar el retorno de la vista completa, no parcial

Aquí es el código de la excepción personalizada filtrar

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

Respuesta

2

Esto es algo que hay que manejar en el navegador. Trate de manejar el error() on jQuery.ajax() call por ejemplo (y obviamente no devuelva la redirección ...).

+0

Esta es la respuesta correcta porque cuando hay un error ajax, no se golpea ni la excepción personalizada ni el código del controlador. – stuartdotnet

0

Puede verificar si la solicitud es una petición de AJAX o no. Usted podría, por ejemplo, haga lo siguiente ...

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 
} 

Sin embargo, como Maxwell dijo que podría dejar que la burbuja excepcion arriba si se trata de una petición Ajax y controlar el error en el cliente. Puede configurar globalmente una forma de manejar excepciones en solicitudes ajax como se describe here

1

Sugeriría que la excepción saltara al cliente y lo manejara como lo sugirió Maxwell.

En nuestro proyecto anterior utilizamos un actionfilter específico para el manejo de errores ajax (tomado de Suteki Shop). Tenga en cuenta que el estado de respuesta es 500 (error interno del servidor). Se requiere un estado de error para la respuesta para llamar al delegado de Error() dentro de una llamada 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

¿Has intentado borrar la respuesta? El controlador aún puede establecer contenido de respuesta.

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

Utilizo OnFailure hanlder en la etiqueta de formulario.

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

... función ajaxFormSucced() {// Código para el éxito } función ajaxFormFailure() {// Código para el fracaso }

0

This te ayudarán.

Solo agregue.IsAjaxRequest método de extensión y devolver 403 código de estado al navegador, jQuery ajaxError lo manejarán volver a dirigir a la página de acceso

0

Como dice Maxwell, manejar en el cliente, usando algo como esto

function handleError(ajaxContext) { 
    // Load parent 
} 

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

lo que debe hacer es sin embargo asegúrese de que en el controlador el código ActionResult para NoAccess contenga el siguiente código, para que se active su error ajax.

HttpContext.Response.StatusCode = 401; 
Cuestiones relacionadas