240 votes

Pratiques exemplaires de ViewModel

À partir de cette question, on dirait qu'il est logique d'avoir un contrôleur de créer un ViewModel qui reflète plus fidèlement le modèle, la vue est d'essayer de l'écran, mais je suis curieux à propos de certaines des conventions (je suis nouveau sur le modèle MVC, si ce n'était pas déjà évident).

Fondamentalement, j'ai eu les questions suivantes:

  1. Normalement, je voudrais avoir un class/fichier. Est-il logique avec un ViewModel si c'est seulement en cours de création pour transférer des données à partir d'un contrôleur de vue?
  2. Si un ViewModel n'appartiennent dans son propre fichier, et que vous utilisez un répertoire/projet de structure pour garder les choses séparées, d'où vient le ViewModel fichier appartient-il? Dans les Contrôleurs de répertoire?

C'est en gros pour l'instant. Je pourrais avoir un peu plus de questions à poser, mais cela a été de me tracasser pour la dernière heure, et je peut sembler à trouver des orientations cohérentes ailleurs.

EDIT: En regardant l'exemple de NerdDinner application sur CodePlex, il semble que le Viewmodel font partie des Contrôleurs, mais il me fait encore mal à l'aise qu'ils ne sont pas dans leurs propres fichiers.

213voto

Ryan Montgomery Points 5153

Je crée ce que j'appelle un "ViewModel" pour chaque vue. Je les ai mis dans un dossier appelé Viewmodel dans mon projet Web MVC. Je leur nom après le contrôleur et l'action (ou de la vue) qu'ils représentent. Donc, si j'ai besoin de transmettre des données à la vue de l'Inscription sur la liste des Membres du contrôleur-je créer un MembershipSignUpViewModel.cs de la classe et de le mettre dans le Viewmodel dossier.

Puis-je ajouter les propriétés nécessaires et des méthodes pour faciliter le transfert de données à partir du contrôleur à la vue. J'utilise le Automapper à obtenir de mon ViewModel pour le Modèle de Domaine et à l'arrière à nouveau si nécessaire.

Cela fonctionne aussi bien pour les composites Viewmodel qui contiennent des propriétés qui sont du type des autres Viewmodel. Par exemple, si vous avez 5 widgets sur la page d'index dans la composition du contrôleur, et vous avez créé un ViewModel pour chaque vue partielle - comment transmettre les données à partir de l'Indice d'action pour les partiels? Vous ajoutez une propriété à la MembershipIndexViewModel de type MyPartialViewModel et lors du rendu de l'partielle, que vous devez passer dans le Modèle.MyPartialViewModel.

Cette façon de faire permet de régler l'partielle ViewModel propriétés sans avoir à modifier l'Index de la vue à tous. Il reste juste passe dans le Modèle.MyPartialViewModel donc il y a moins de chance que vous aurez à passer par l'ensemble de la chaîne de partiels à réparer quelque chose quand tout ce que vous avez à faire est d'ajouter une propriété à l'partielle ViewModel.

Je vais aussi ajouter l'espace de noms "MyProject.Web.ViewModels" sur le web.config afin de me permettre de faire référence à tout point de vue, sans jamais l'ajout explicite d'une instruction d'importation sur chaque vue. Il fait juste un peu plus propre.

129voto

Max Toro Points 13050

La séparation des classes par catégorie (les Contrôleurs, les ViewModels, des Filtres, etc.) est un non-sens.

Si vous voulez écrire du code pour la section d'Accueil de votre site ( / ), puis créez un dossier nommé à la Maison, et y mettre le contrôleur HomeController, IndexViewModel, AboutViewModel, etc. et de toutes les classes utilisées par la Maison des actions.

Si vous avez partagé des classes, comme un ApplicationController, vous pouvez le mettre à la racine de votre projet.

Pourquoi séparer les choses qui y sont liés (HomeController, IndexViewModel) et de garder l'ensemble des choses qui n'ont aucun rapport (HomeController, AccountController) ?


J'ai écrit un post de blog sur ce sujet.

21voto

Mark Points 2832

- Je garder mes classes de l'application dans un sous-dossier appelé "de Base" (ou une autre bibliothèque de classe) et d'utiliser les mêmes méthodes que la KIGG exemple d'application, mais avec quelques légères modifications à faire mes applications les plus SECS.

J'ai créer un BaseViewData classe /Core/ViewData/ où je stocke site commun les propriétés à l'échelle.

Après cela, j'ai aussi créer toutes de mon point de vue ViewData classes dans le même dossier qui dérivent ensuite BaseViewData et ont vue de leurs propriétés spécifiques.

Puis-je créer un ApplicationController que tous mes contrôleurs de dériver. ApplicationController a un générique GetViewData Méthode comme suit:

protected T GetViewData<T>() where T : BaseViewData, new()
    {
        var viewData = new T
        {
           Property1 = "value1",
           Property2 = this.Method() // in the ApplicationController
        };
        return viewData;
    }

Enfin, dans mon Contrôleur de l'action je ne les suivants pour construire mon ViewData Modèle

public ActionResult Index(int? id)
    {
        var viewData = this.GetViewData<PageViewData>();
        viewData.Page = this.DataContext.getPage(id); // ApplicationController
        ViewData.Model = viewData;
        return View();
    }

Je pense que cela fonctionne vraiment bien et il maintient votre point de vue et bien rangé vos contrôleurs maigre.

13voto

JMS Points 1121

Une classe ViewModel est là pour encapsuler plusieurs morceaux de données représentées par des instances de classes dans un facile pour gérer l’objet que vous pouvez passer à votre vue.

Il serait judicieux d’avoir vos classes ViewModel dans leurs propres fichiers dans le répertoire propre. Dans mes projets, j’ai un sous-dossier du dossier modèles appelé ViewModels. C’est là mon ViewModels (par exemple `` ) en direct.

13voto

zihotki Points 4729

Il n'y a aucune place pour garder vos modèles. Vous pouvez les conserver dans l'assemblée distincte si le projet est grand et il y a beaucoup de Viewmodel (Objets de Transfert de Données). Vous pouvez aussi les conserver dans le dossier distinct du site de projet. Par exemple, dans l' Oxite ils sont placés dans l'Oxite projet qui contient beaucoup de différentes classes. Les contrôleurs de Oxite sont déplacés pour séparer les projets et les vues sont en projet distinct.
Dans CodeCampServer Viewmodel sont nommés *Forme et ils sont placés dans de l'INTERFACE dans le dossier Modèles.
Dans MvcPress projet, ils sont placés dans les Données du projet, qui contient également tous les code pour travailler avec la base de données et un peu plus (mais je n'ai pas de recommander cette approche, c'est juste un exemple)
De sorte que vous pouvez le voir il ya beaucoup de points de vue. J'ai l'habitude de garder mon Viewmodel (DTO objets) dans le site du projet. Mais quand j'ai plus de 10 modèles, je préfère déplacer eux de se séparer de l'assemblée. Habituellement, dans ce cas, je me déplace contrôleurs de séparer assemblée de trop.
Une autre question est de savoir comment faire correspondre facilement toutes les données de modèle de votre ViewModel. Je suggère de jeter un coup d'oeil à AutoMapper de la bibliothèque. Je l'aime beaucoup, il fait tout le sale boulot pour moi.
Et moi aussi je vous suggère de regarder SharpArchitecture projet. Il offre une très bonne architecture pour des projets et qu'il contient beaucoup de fraîcheur, des cadres et des lignes directrices et une grande communauté.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X