2010-01-02 6 views
0

Je cet exemple de code:Obtenir l'entité utilisatrice actuelle dans ASP.Net MVC

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> 
<% 
    if (Request.IsAuthenticated) { 
%> 
     Welcome <b><%= Html.Encode(Page.User.Identity.Name) %></b>! 

Le hic est que je suis en train de de l'ID utilisateur et pas le nom dans le champ « nom d'utilisateur »:

User user = _userRepository.Get(...); 
FormsAuthentication.RedirectFromLoginPage(user.Id.ToString(), false); 

Le premier exemple de code est inclus dans la vue principale et apparaît ainsi dans chaque vue. Ce que je ne comprends pas, c'est comment passer cette vue à l'entité du modèle Utilisateur, puisque je ne l'appelle pas directement.

Modifier: Existe-t-il un seul point dans le traitement d'une requête HTTP où je peux intervenir pour injecter l'objet Modèle utilisateur dans ViewData? Je ne voudrais pas toucher chaque contrôleur + action pour y parvenir.

Répondre

1

La solution de contournement la plus courante consiste à stocker l'utilisateur dans une variable de session. Je dirais que c'est aussi le moyen le plus populaire même dans ASP.NET MVC.

Dans une classe utilitaire ou classe de base page/UserControl personnalisée:

const string _userSessionKey = "CurrentUser_"; 
public UserModelType CurrentUser 
{ 
    var user = HttpContext.Current.Session[_userSessionKey] as UserModelType; 
    if(user == null) 
    { 
     if(HttpContext.Current.User.Identity.IsAuthenticated) 
     { 
      //new UserService() or DependencyContainer.Resolve<IMembershipService>() 
      user = new MembershipService().GetUserById(HttpContext.Current.User.Identity.Name); 
      HttpContext.Current.Session[_userSessionKey] = user; 
     } 
    } 

    return user; 
} 

Je sais!
Ceci est trop classique et probablement pas MVC-ish, mais généralement, je vois des implémentations similaires.

La chose la plus importante pour garder ce MVC amical est d'avoir ce code mieux appelé depuis un contrôleur. Vous pouvez utiliser un contrôleur partiel qui sort un contrôle utilisateur ou plus (il existe une méthode RenderAction que je considère comme l'une des meilleures parties). Alors que la vue est seulement passé le nom de l'utilisateur ou le modèle de l'utilisateur ne l'appelle pas directement. C'est pourquoi une classe d'utilitaires ici est bien meilleure qu'une classe de base/classe de contrôle, mais il y a les options en général.

Si vous voulez que la plus belle des choses que vous devriez rechercher quelque chose comme:

ASP.Net MVC Membership Starter Kit

+0

Mais je devrais appeler ce code de chaque contrôleur alors, en violant DRY? – ripper234

+0

Non! Vous le faites dans une classe utilitaire, appelez-le à partir d'un contrôleur partiel dont la vue est un contrôle utilisateur. Ensuite, vous appelez méthode RenderAction <>() dans n'importe quelle vue qui doit afficher ceci, généralement dans la page maître pas dans une vue. Si vous avez besoin d'accéder à l'utilisateur à d'autres fins plus tard d'un autre contrôleur, vous appelez la propriété de la classe d'utilité. – Meligy

+0

Avez-vous d'autres préoccupations? Avez-vous essayé et le faire fonctionner? – Meligy

1

Ce que j'ai installé sur est la création d'une vue maître de classe modèle que presque tous les modèles spécifiques à vue dérive. Le modèle maître contient les informations dont chaque vue peut avoir besoin. J'essaie de garder cette information très petite et la cache dans la session afin que le remplissage du modèle ne soit pas une opération intensive. Le modèle implémente une interface pour que chaque modèle spécifique à la vue puisse également implémenter cette interface et, par conséquent, je peux facilement créer une vue fortement typée qui accepte l'interface si je me soucie seulement des informations de base. J'utilise un contrôleur de base pour tous mes contrôleurs et le code pour remplir le modèle de base est implémenté sur le contrôleur de base. Chaque modèle de vue spécifique a un constructeur qui prend l'interface du modèle de base et copie les données dans l'instance locale.

1

Vous pouvez vous assurer que chaque contrôleur/page/contrôle implémente une classe de base dans laquelle vous exposez les données de modèle que vous recherchez.

Cela a tendance à être douloureux, assez rapidement, mais il est plus facile de faire passer un ViewModel que de toucher le HttpContext depuis la page elle-même.

Edit: Ceci est l'un des rares cas où je pourrais être enclin à aller avec le Viewdata [ « nom d'utilisateur »] et l'utiliser dans le MasterPage, au moins de cette façon que la classe de base doit remplir ce et vous pouvez éviter la connaissance de l'authentification à travers vos contrôleurs.

+0

Existe-t-il un seul point dans le traitement d'une requête HTTP où je peux intervenir pour injecter l'objet Modèle utilisateur dans ViewData? Je ne voudrais pas toucher chaque contrôleur + action pour y parvenir. – ripper234

Questions connexes