2009-10-22 20 views
17

¿Cuál es una forma elegante de aprovechar los atributos existentes [HandleError] y [Authorize] cuando se trata de llamadas XHR desde javascript?asp.net mvc [handleerror] [autorizar] con JsonResult?

Por lo tanto, digamos, por ejemplo, un método GetJson que devuelve un JsonResult.

Cuando se produce un error, el método [HandleError] enviará un ViewResult que se recuperará en la función de devolución de llamada en javascript.

Me entonces tiene que colocar el código personalizado en todas partes en javascript para manejar y redirigir ningún tipo de accidentes, etc.

Lo que me gustaría hacer, es tener la [HandleError] atribuyen devolver un JsonResult si el original la acción estaba planeando hacer eso. Esto podría ser una ilusión de mi parte.

Del mismo modo, si aparece una solicitud Json no autorizada, en lugar de devolver un nuevo HttpUnauthorizedResult, me gustaría devolver un JsonResult que permita que mi código del lado del cliente maneje las cosas de manera común.

¿Estoy ladrando el árbol equivocado aquí? ¿Tal vez hay una manera aún más agradable de que MVC pueda manejar esto que no conozco?

¿Cómo están manejando este escenario otras personas?

Gracias.

PD: Me doy cuenta de que puedo crear mis propios atributos [HandleJsonError] y [AuthorizeJson] que devuelven JsonResults en lugar de ViewResults, pero luego tendría que dar la vuelta y colocarlos en cualquier método que devuelva Json, y preocuparme por Orden de filtro, etc. Seguramente estaría bien si pudiera usar la reflexión o algo para que el mismo atributo actúe de manera diferente dependiendo de la firma del método original.

Respuesta

27

No es así. En este momento, no ayudan con JSON. Sin embargo:

que se dan cuenta de que puedo crear mi propia [HandleJsonError] y [] AuthorizeJson atributos que volver JsonResults en lugar de ViewResults, pero entonces tendría que dar la vuelta y colocarlos en cualquier método que devuelve JSON, y preocuparse por orden del filtro etc.

lo que hicimos es subtipo los atributos existentes, y hacer que funcionen de forma condicional:

public sealed class AjaxAuthorizeAttribute : AuthorizeAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     base.OnAuthorization(filterContext); 
     if (filterContext.Result == null) 
     { 
      return; 
     } 
     else if (filterContext.Result.GetType() == typeof(HttpUnauthorizedResult) 
      && filterContext.HttpContext.Request.IsAjaxRequest()) 
     { 
      filterContext.Result = new ContentResult(); 
      filterContext.HttpContext.Response.StatusCode = 403; 
     } 
    } 
} 

Ahora el código JS puede mirar fo r 403 (porque ASP.NET come 401 y devuelve la página de error) y el mismo atributo funciona para Ajax y no Ajax. Entonces, no hay problemas de orden de filtro.

+0

Gracias! Request.IsAjaxRequest() es muy útil. No sabía que existía. – Scott

+0

Es un método de extensión que MVC agrega. En realidad, no es parte de Request. –

+1

¡Gracias! Esa es una forma muy elegante y debe marcarse como la respuesta correcta. El constructor no es necesario sin embargo. –

Cuestiones relacionadas