ASP.NET MVC - comment utiliser exactement les Modèles de vue

Disons que j'ai une page qui permet l'édition des détails d'un utilisateur, donc j'ai un ViewModel comme ceci:

public class UserViewModel {
    public string Username { get; set; }
    public string Password { get; set; }
    public int ManagerId { get; set; }
    public string Category { get; set; }
}

Donc, sur mon action EditUser, je peux le renvoyer par le classeur de modèle et ensuite je peux le mapper au Modèle De Domaine:

public ActionResult EditUser(UserViewModel user) {
    ...

Cependant, la page qui affiche le formulaire a également besoin de détails tels qu'une liste de gestionnaires et de catégories pour fournir des listes déroulantes pour ces champs. Il peut également afficher une liste d'autres utilisateurs dans une barre latérale afin que vous puissiez basculer entre le différents utilisateurs que vous modifiez.

Alors j'ai un autre modèle de vue:

public class ViewUserViewModel {
    public UserViewModel EditingUser { get; set; }
    public IEnumerable<SelectListItem> Managers { get; set; }
    public IEnumerable<SelectListItem> Categories { get; set; }
    public IEnumerable<SelectListItem> AllUsers { get; set; }
}

Est-ce la bonne façon de le faire? Sont-ils les deux modèles de vue? Si oui, y a-t-il une convention de nommage que je devrais utiliser pour pouvoir distinguer entre les machines virtuelles qui sont comme des modèles et les machines virtuelles qui contiennent uniquement des données pour la page?

Ai-je tout faux?

36
demandé sur littlecharva 2013-05-14 20:32:47

3 réponses

Comment je fais cela dans le raccourci:

  1. créez une classe ViewModel séparée pour chaque formulaire sur la page, puis je rends ces classes avec PartialViews comme @{Html.RenderPartial("PartialName", Model.PartialModel);}.
  2. si la page contient des choses comme HTML metas, je crée une classe séparée pour metas et la place dans la section sur la page.
  3. cas Rest comme "Devrais-je mettre ceci dans une classe séparée?"votre jugement.

Par exemple, vous avez une page qui a une sorte de barre de connexion / registre ou de popup quoi.

public class SomePageViewModel
{
    public RegisterBarVM Register { get; set; }
    public LoginBarVM LoginBar { get; set; }

    public MetasVM Metas { get; set; }
    public string MaybePageTitle { get; set;}
    public string MaybePageContent { get; set;}

    [HiddenInput(DisplayValue = false)]
    public int IdIfNeeded { get; set; }

    public IEnumerable<SelectListItem> SomeItems {get; set;}
    public string PickedItemId { get;set; }
}

public class RegisterBarVM
{
    public string RegisterUsername {get;set;}
    public string RegisterPassword {get;set;}
    //...
}

public class LoginBarVM
{
    public string LoginUserame {get;set;}
    public string LoginPassword {get;set;}
    //...
}

//cshtml
@model yourClassesNamespace.SomePageViewModel
@{
    Html.RenderPartial("LoginBar", Model.LoginBar); //form inside
    Html.RenderPartial("RegisterBar", Model.RegisterBar); //form inside

    using(Html.BeginForm())
    {
        @Html.EditorFor(m => m.IdIfNeeded)
        @Hmtl.EditorFor(m => m.MaybePageTitle)
        @Hmtl.EditorFor(m => m.MaybePageContent)

        @Hmtl.DropDownListFor(m => m.PickedItemId, new SelectList(Model.SomeItems))

        <input type="submit" value="Update" />
    }
}

@section Metas {
    @{Html.RenderPartial("Meatas", Model.Metas}
}

À propos des modèles d'éditeur Brad Wilsons Blog {[16] } et juste google ou chercher des piles de ressources sur les modèles d'affichage / Éditeur et HtmlHelpers. Ils sont tous très utiles pour construire des sites Web cohérents.

20
répondu Mariusz 2013-05-14 21:20:57

"Voir le modèle" est juste un modèle. Il n'y a rien de magique dans le nom, mais généralement toute classe transmise à une vue (que ce soit pour simplement afficher des données ou à des fins de soumission de formulaire) est appelée "modèle de vue" et reçoit un nom comme FooViewModel ou FooVM pour indiquer que cela fait partie de ce modèle de "modèle de vue".

Je ne veux pas aller trop philosophique sur vous, mais je pense qu'un peu de référence sur les modèles en jeu sera utile. ASP.NET MVC évidemment assez encourage un MVC (Modèle-Vue-Contrôleur) modèle architectural. Dans MVC, le modèle est le conteneur de toute la logique métier de l'application . Le contrôleur est responsable de la gestion de la requête, de la récupération du modèle, du rendu de la vue avec ce modèle et du retour d'une réponse. Cela semble être beaucoup de responsabilité, mais en réalité, le framework gère la plupart de cela dans les coulisses, donc les contrôleurs sont généralement (et devraient être) très légers sur le code. Ils sont responsables du nu quantité minimale de fonctionnalités pour tout câbler. Enfin, il est responsable de la création de la couche d'INTERFACE utilisateur qui permet à l'utilisateur d'interagir avec les données dans le Modèle. Il est Pas responsable des données elles-mêmes, et il ne devrait pas être (ViewData / ViewBag est une violation assez grande ici, au moins dans la mesure où il finit par être utilisé par les développeurs dans la pratique).

Donc, cela signifie que la majeure partie de votre logique d'application devrait être dans votre modèle, et généralement c'est une bonne chose. Cependant, puisque le modèle est le refuge des données d'application, il est généralement conservé dans une base de données ou similaire. Cela crée un conflit d'intérêts car vous devez maintenant établir un équilibre entre les données qui doivent être conservées et celles qui ne doivent exister qu'à des fins d'affichage.

C'est là que les modèles de vue entrent en jeu. MVVM (Model-View-View Model), un modèle quelque peu parallèle à MVC, reconnaît les problèmes inhérents à une approche one-model-to-rule-them-all. Je n'entrerai pas dans beaucoup détail ici, car MVC n'utilise pas ce modèle. Cependant, la plupart ASP.NET les développeurs MVC ont coopté le modèle de vue de MVVM. Ce que vous vous retrouvez essentiellement avec une entité (le modèle traditionnel), puis généralement de nombreux modèles de vue différents qui représentent cette entité dans différents états. Cela permet à votre modèle de contenir la logique métier pertinente pour la persistance, tandis que le ou les modèles de vue contiennent la logique métier pertinente pour l'affichage, la création et la mise à jour modèle.

J'ai un peu dérapé, mais le long et le court est que ce que vous faites est parfaitement acceptable. En fait, c'est une bonne pratique. Créez autant de modèles de vue que votre application l'exige et utilisez-les pour stocker les données et la logique métier nécessaires à vos vues. (Cela inclut des choses comme SelectList s. ni votre contrôleur ni votre vue ne devraient avoir besoin de savoir comment créer un SelectList pour une liste déroulante.)

94
répondu Chris Pratt 2013-05-14 18:28:10

Personnellement, je préfère mettre toutes les informations requises pour que la page soit rendue dans le ViewModel, car c'est le but du ViewModel - fournir toutes les données pour la vue. Donc, mon UserViewModel contiendrait des propriétés pour Managers, Categories et AllUsers et le contrôleur remplirait ces collections avant de passer le ViewModel à la vue.

C'est essentiellement ce que vous avez fait - il supprime simplement le ViewModel supplémentaire de l'équation.

J'ai aussi vu d'autres les programmeurs utilisent ViewData pour envoyer les listes déroulantes à la vue, mais je n'aime pas cela parce que ViewData n'est pas fortement typé, alors qu'un ViewModel l'est.

9
répondu Jason Berkan 2013-05-14 16:38:11