2010-03-12 3 views
3

Donc, je suis dans une situation, où j'ai besoin d'afficher une vue différente basée sur le "rôle" que l'utilisateur authentifié a.ASP.NET MVC Actions qui retournent des vues différentes, ou font juste une tonne d'actions?

Je me demande quelle approche est la meilleure ici:

[Authorize(Roles="Admin")] 
public ActionResult AdminList(int? divID, int? subDivID) 
{ 
    var data = GetListItems(divID.Value, subDivID.Value); 
    return View(data); 
} 

[Authorize(Roles = "Consultant")] 
public ActionResult ConsultantList(int? divID, int? subDivID) 
{ 
    var data = GetListItems(divID.Value, subDivID.Value); 
    return View(data); 
}    

ou dois-je faire quelque chose comme ça

[Authorize] 
public ActionResult List(int? divID, int? subDivID) 
{ 
    var data = GetListItems(divID.Value, subDivID.Value); 
    if(HttpContenxt.User.IsInRole("Admin")) 
    { return View("AdminList", data); } 

    if(HttpContenxt.User.IsInRole("Consultant")) 
    { return View("ConsultantList", data); } 

    return View("NotFound"); 
} 
+0

Le premier semble être plus facile à lire et à maintenir probablement. –

+4

@Developer Art - sauf que votre vue devra savoir quelle action appeler en fonction du rôle. Il vaut mieux que le contrôleur détermine quelle vue utiliser en fonction du rôle de l'OMI. – tvanfosson

+0

C'est ce que je pensais aussi, mais je voulais juste voir si quelqu'un d'autre réfléchissait à ça aussi et a pris une résolution différente de celle que j'ai eue. – Nate

Répondre

5

Dans le cas où l'action est la même sur le plan conceptuel, mais l'affichage est différent, je voudrais avoir une action et retourner des vues différentes en fonction de votre discriminateur. J'irais avec votre deuxième exemple, légèrement modifié. Notez qu'il n'est pas nécessaire d'obtenir les données si l'utilisateur n'est pas dans un rôle approprié.

[Authorize] 
public ActionResult List(int? divID, int? subDivID) 
{ 
    var view = HttpContext.User.IsInRole("Admin") 
        ? "AdminList" 
        : (HttpContext.User.IsInRole("Consultant") 
         ? "ConsultantList" 
         : null); 
    if (view == null) 
    { 
     return View("NotFound"); 
    } 

    var data = GetListItems(divID.Value, subDivID.Value); 

    return View(view, data); 
} 

Vous vous rendez compte, bien sûr, que vous avez la possibilité d'une exception non gérée lorsque vous faites référence à la valeur d'une Nullable<int> potentiellement nulle, non? En outre, vous pourriez, si vous le faites fréquemment, refactoriser la construction du préfixe de la vue en une méthode commune.

public string GetRolePrefix() 
{ 
    return HttpContext.User.IsInRole("Admin") 
        ? "Admin" 
        : (HttpContext.User.IsInRole("Consultant") 
         ? "Consultant" 
         : null); 
} 

Ensuite, appelez comme

... 
var prefix = GetRolePrefix(); 
if (prefix == null) 
{ 
    return View("NotFound"); // more likely "NotAuthorized" ??? 
} 

...get model... 

return View(prefix + "List", data); 
+0

Oui, le code que j'ai posté est abrégé ...;) – Nate

5

Je préfère la deuxième méthode, mais je pense que votre contrôleur pourrait être rangea un peu. Il y a trop de logique là-dedans à mon goût, ce qui pourrait potentiellement augmenter au fur et à mesure que d'autres rôles sont ajoutés.

Une approche serait de remanier le rôle laid code de vérification dans une couche de service (qui pourrait être injecté si vous utilisez un conteneur IoC):

[Authorize] 
public ActionResult List(int? divID, int? subDivID) 
{ 
    var permission = _userService.GetKeyRole(HttpContext.User); 
    if(permission != null) 
    { 
     var data = GetListItems(divID.Value, subDivID.Value); 
     return View(permission + "List", data); 
    } 
    return View("NotFound"); 
} 

Et la méthode extrait:

public class UserService : IUserService 
{ 
    public string GetKeyRole(IPrincipal user) 
    { 
     if(user.IsInRole("Admin")) return "Admin"; 
     if(user.IsInRole("Consultant")) return "Consultant"; 
     return null; 
    } 
} 
-1

Voici une troisième approche. C'est une combinaison des deux approches suggérées par Nate, qui conserve une place unique pour la logique comme dans la seconde approche, mais divise les utilisateurs en actions comme dans le premier.

[ChildActionOnly] 
public ActionResult List(int? divID, int? subDivID) 
{ 
    var data = GetListItems(divID.Value, subDivID.Value); 
    return View(data); 
} 

[Authorize(Roles="Admin")] 
public ActionResult AdminList(int? divID, int? subDivID) 
{ 
    return List(divID, subDivID); 
} 

[Authorize(Roles = "Consultant")] 
public ActionResult ConsultantList(int? divID, int? subDivID) 
{ 
    return List(divID, subDivID); 
} 

L'astuce est que MVC va essayer de rechercher des vues nommées par l'action de la demande plutôt que celle qui produit la sortie. Ainsi, lorsque vous exécutez AdminList, l'action List s'affiche avec la vue AdminList. Editer: Le downvote pour ne pas avoir répondu correctement à la question? Laissez-moi reformuler ma réponse.

Questions connexes