2009-10-22 6 views
17

Quelle est la manière élégante de tirer parti des attributs [HandleError] et [Authorize] existants lors du traitement des appels XHR depuis javascript? Par exemple, par exemple une méthode GetJson qui retourne un JsonResult.asp.net mvc [handleerror] [autoriser] avec JsonResult?

Lorsqu'une erreur survient, la méthode [HandleError] renvoie un ViewResult qui sera renvoyé dans la fonction de rappel en javascript.

Je dois alors placer un code personnalisé partout en javascript pour gérer et rediriger les accidents, etc.

Ce que je voudrais faire, est d'avoir la [HandleError] attribut renvoie une JsonResult si l'original l'action prévoyait de le faire. Ce pourrait être un vœu pieux de ma part.

De même, si une requête JSON non autorisée arrive, au lieu de renvoyer un nouveau HttpUnauthorizedResult, j'aimerais retourner un JsonResult qui permette à mon code client de gérer les choses d'une manière courante.

Est-ce que j'aboie le mauvais arbre ici? Peut-être y a-t-il une façon encore plus agréable que MVC puisse gérer cela que je ne connais pas?

Comment les autres personnes manipulent-elles ce scénario?

Merci. PS: Je réalise que je peux créer mes propres attributs [HandleJsonError] et [AuthorizeJson] qui renvoient JsonResults au lieu de ViewResults, mais je dois alors les placer sur n'importe quelle méthode qui renvoie Json et m'inquiéter de Ordre de filtre etc. Il serait bien que je puisse utiliser une réflexion ou quelque chose pour que le même attribut agisse différemment selon la signature de la méthode originale.

Répondre

27

Vous ne le faites pas. En ce moment, ils ne aident pas avec JSON. Cependant:

Je me rends compte que je peux créer mon propre [HandleJsonError] et [AuthorizeJson] attributs qui reviennent JsonResults au lieu de ViewResults, mais je dois faire le tour et les placer sur une méthode qui retourne JSON, et vous soucier de l'ordre des filtres, etc.

Ce que nous avons fait est de sous-type les attributs existants, et de les faire travailler sous condition:

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

maintenant le code JS peut regarder fo r 403 (car ASP.NET mange 401 et renvoie la page d'erreur) et le même attribut fonctionne pour Ajax et non-Ajax. Donc, aucun problème de commande de filtre.

+0

Merci! Request.IsAjaxRequest() est très utile. Je ne savais pas que ça existait. – Scott

+0

C'est une méthode d'extension ajoutée par MVC. Cela ne fait pas partie de la demande. –

+1

Merci! C'est un moyen très élégant et devrait être marqué comme la bonne réponse. Le constructeur n'est pas nécessaire cependant. –

Questions connexes