2009-03-12 16 views
1

Je voudrais fournir l'instance de l'utilisateur connecté (ou null si personne n'a encore ouvert de session) pour toutes les vues de mon application MVC. J'ai déjà implémenté avec succès ma propre classe ControllerActionInvoker qui remplace InvokeAction et fournit une instance d'utilisateur connectée dans ViewData (controllerContext.Controller.ViewData ["LoggedUser"] = xxx). Le problème est que je voudrais utiliser le modèle fortement typé pour passer l'instance d'utilisateur connecté dans l'application entière. Je pensais avoir une classe ApplicationViewDataBase qui pourrait être une classe de base pour toutes mes classes ViewData fortement typées et qui fournirait également une instance d'utilisateur connecté. Je pourrais facilement accéder à l'instance d'utilisateur connecté dans toutes mes vues.MS MVC - Puis-je globalement remplir ViewData/Model fortement typé pour toutes mes vues?

Est-il possible de remplir globalement le typage fort comme je l'ai réalisé dans ControllerActionInvoker.InvokeAction override? Ou est-il préférable de fournir en quelque sorte mon instance d'utilisateur dans Page.User? Je trouverais probablement plus de slick à utiliser Page.User, mais n'a pas non plus trouvé de solution pour injecter mon instance User ...

Répondre

1

Peut-être une meilleure façon de mettre l'utilisateur dans le HttpContext? Dans global.asax

Application_AuthenticateRequest protected void (object sender, EventArgs e)

0

Vous n'avez pas besoin d'ajouter ceci; il est déjà disponible dans ASP.NET MVC. Regardez ViewContext.HttpContext.User.Identity.Name

+0

Je pense que vous manquez le point. Il est courant pour les applications d'avoir une classe d'utilisateurs personnalisée qui stocke les détails spécifiques à l'application pour l'utilisateur connecté. Le problème n'est pas de savoir qui a ouvert une session, il charge cet objet utilisateur depuis la base de données suffisamment tôt dans la gestion des réponses pour que tout le code concerné puisse y accéder. – christutty

1

Ceci est une vieille question donc juste pour le bénéfice des futurs visiteurs, cela peut être fait en créant un basecontroller hérité de Controller et en gérant OnActionExecuted() pour ajouter votre utilisateur personnalisé instances à la vue entre l'action du contrôleur et la vue. Il y a une implémentation complète de cela ici: http://blog.bitdiff.com/2012/05/sharing-common-view-model-data-in.html

Si vous voulez que les données soient disponibles pour votre méthode d'action, les choses deviennent un peu plus compliquées car la vue n'existe pas encore. Pour les méthodes POST "baseView = filterContext.Controller.ViewData.Model comme BaseView" vous donnera accès à la vue, mais vous aurez besoin d'un modelbinder personnalisé pour définir ViewData.Model (voir https://stackoverflow.com/a/25250058/2381157). Malheureusement, il ne s'agit pas d'une solution globale car ModelBinder n'est pas invoqué à moins qu'il y ait quelque chose à lier.

Une approche qui pourrait convenir est un filtre ActionFilter ou AttributeFilter qui injecte une valeur à RouteData ou ActionParameters mais votre action devrait transférer cette valeur à la vue. Je n'ai pas trouvé de manière simple et efficace d'injecter ces données dans la vue telle qu'elle a été créée et je suis revenu à l'implémentation d'un cache thread-safe des instances d'utilisateur afin de pouvoir récupérer l'instance de l'utilisateur chaque fois que nécessaire. sans le surcoût de requête de base de données. Ce n'était pas facile mais cela avait d'autres avantages pour conserver l'état de l'utilisateur entre les requêtes croisées (ce qui est généralement la raison pour laquelle vous voudriez avoir des données utilisateur personnalisées disponibles pour la logique du contrôleur).