2009-02-05 8 views
8

Je suis relativement nouveau à MVC, donc c'est probablement une question novice. J'essaie de comprendre les meilleures pratiques sur la façon de maintenir une séparation claire des préoccupations dans quelques scénarios qui ne semblent pas aller droit au but.Modèles spécifiques à la vue dans ASP.NET MVC?

Je regarde actuellement deux scénarios. Imaginez une application très basique qui permet aux utilisateurs de visualiser et de modifier les profils en ligne pour les avocats. Il existe une action/vue pour afficher le profil d'un utilisateur particulier et une action/vue pour modifier le profil d'un utilisateur particulier. Il est facile d'imaginer une classe Model sympa et propre pour représenter les détails du profil d'un utilisateur, peut-être réalisé avec Entity Framework et mappé à la table SQL du profil utilisateur.

Dans l'action vue/vue pour afficher le profil d'un utilisateur, fonctionnellement, j'ai besoin d'un bouton ou un lien qui permet à un utilisateur de modifier le profil. Mais cela ne devrait être disponible que pour un sous-ensemble d'utilisateurs. Par exemple, l'utilisateur peut modifier son propre profil. En outre, les super-utilisateurs peuvent modifier le profil de n'importe qui. Ma question est de savoir comment la vue devrait décider si le lien devrait être là lors du rendu d'un profil particulier. Je suppose qu'il est incorrect pour la vue de contenir la logique pour déterminer si l'utilisateur actuel peut modifier le profil en cours. Dois-je ajouter une propriété IsEditable à la classe de modèle UserProfile? Cela ne me semble pas tragique, mais cela ne me semble pas non plus tout à fait correct. Dois-je créer une nouvelle classe Modèle qui agrège le profil utilisateur avec des informations supplémentaires sur la sécurité? Un autre scénario ... Lors de l'édition d'un profil particulier, l'un des éléments modifiables est la liste des spécialités pour un avocat particulier. La liste des spécialités possibles n'est pas fixe. Si la vue veut les afficher dans une liste déroulante, il faut la liste de toutes les spécialités possibles de la base de données. La vue ne devrait pas les obtenir directement à partir de la base de données, alors est-ce que je refais l'objet Model et fournissais à la vue à la fois le profil UserProfile et une liste de spécialités valides? Je suppose que le problème générique que j'essaie de comprendre est que je devrais être à l'aise avec la création de nombreuses petites classes de modèles qui sont essentiellement spécifiques aux vues individuelles. Chaque classe inclut les différentes parties non liées du modèle de domaine plus grand nécessaire pour cette vue particulière.

Répondre

2

Pour votre scénario, je transmets un autre paramètre dans ViewData, ViewData ["AllowEdit"] qui est défini sur true si la vue doit afficher le lien d'édition. Je préfère ceci au clonage du modèle dans un modèle spécifique à la vue pour ajouter cet attribut unique. Je crée parfois des modèles spécifiques à la vue - par exemple, j'ai Grid ViewUserControl qui prend un modèle Grid, que je peux produire à partir de n'importe quelle liste d'autres classes de modèles - mais je ne le ferais pas dans ce cas.

À mon avis, je ferais quelque chose comme ceci:

<% if (Convert.ToBoolean(ViewData["AllowEdit"])) { %> 
<%= Html.ActionLink("Edit", "Edit", "Profile", 
        new { id = ViewData.Model.ID }, null) %> 
<% } %> 
1

Pour votre première situation, je probablement essayer de résumer la logique pour cela dans le modèle de profil, peut-être avec une fonction comme CanEdit() qui accepte les paramètres d'informations utilisateur et vérifie si l'utilisateur est le propriétaire du profil ou s'il dispose d'autorisations de superutilisateur. Ensuite, dans le contrôleur, j'appellerais la fonction et passerais les résultats à la vue en utilisant ViewData. Pour la seconde, dans l'action d'édition du contrôleur de profil, récupérez la liste des spécialités (via le modèle) et transmettez-la à la vue à l'aide de ViewData.

0

Vous pouvez créer une classe de modèle de base pour toutes vos classes de modèle de vue et y inclure des informations qui peuvent être considérées comme utiles dans de nombreuses vues, même si elles ne le sont pas toutes. Par exemple, l'ID de l'utilisateur actuellement connecté.

public class BaseModel 
{ 
    Guid ActiveUserId; 
} 

public class EditModel : BaseModel 
{ 
    Guid AuthorUserId; 
} 

Alors, à votre avis, vous pouvez faire une comparaison de base:

<% if (Model.ActiveUserId == AuthorUserId) 
    Response.Write (Html.ActionLink (.....)) %> 

Cette simple vérification est tout à fait correct, il n'y a pas beaucoup de la logique et de toute façon, quelqu'un doit décider si ce lien doit apparaître . Vous pouvez faire bien sûr deux vues différentes, avec le lien et sans un, mais c'est plutôt exagéré.

3

Le modèle ViewModel est plus spécifiquement orienté vers le scénario que vous avez décrit. Vous pouvez utiliser le ViewData mais c'est la solution la moins recommandée puisque vous perdez beaucoup des avantages du framework ASP.NET MVC. Par exemple, lorsque vous utilisez ViewData, vous ne disposez pas de la sécurité de type, de la compilation et du support intellisense dans vos vues.

Questions connexes