2010-10-14 7 views
3

J'ai 3 tables many-many: Users -<UserRoles>- Roles. Je mis mon modèle comme celui-ci:ASP.NET MVC plusieurs à plusieurs modèle sur le côté client

public class User 
{ 
    public int UserId {get; set;}; 
    public IEnumerable<Role> Roles {get; set;}; 
} 

public class Role 
{ 
    public int RoleId {get; set;}; 
    public string RoleName {get; set}; 
} 

public class UserDisplayModel 
{ 
    public User User{get; set;}; 
    public IEnumerable<Role> AllRoles {get; set;} 
} 

Lors de l'édition/création de l'utilisateur, comment puis-je obtenir la case cochée des rôles dans le contrôleur et comment pourrais-je régler cela à mon avis?

Si je me trompe dès le début sur la façon dont j'ai configuré mon modèle, dites-moi s'il vous plaît et aidez-moi sur la façon dont je ferais cela.

Merci.

Répondre

1

La clé est que vous avez besoin de votre collection correctement rendu dans la vue. Tout d'abord, ajoutez une propriété booléenne aux données de vue le rôle objet que nous avons quelque chose à lier notre case à cocher pour:

public class Role 
{ 
    public bool IsInRole { get; set; } 
    [HiddenInput(DisplayValue = false)] 
    public int RoleId { get; set; } 
    [HiddenInput(DisplayValue = true)] 
    public string RoleName { get; set; } 
} 

Avis je mets un attribut de HiddenInput sur les propriétés (plus tard). Vous pouvez également passer votre objet Utilisateur comme indiqué ci-dessus à la vue - ceci a déjà la collection de Rôles enfants. Il y a quelques façons de rendre cette collection dans la vue, mais l'un des plus simple est:

<%: Html.EditorFor(m => m.Roles) %> 

ajouter maintenant un modèle d'éditeur pour l'objet de rôle pour que la ligne ci-dessus fait ce que nous voulons. Ajoutez le fichier Role.ascx dans/Views/Shared/EditorTemplates. Roles.ascx peut regarder quelque chose comme ceci:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<MvcApplication5.Controllers.Role>" %> 
<%: Html.EditorFor(m => m.IsInRole) %> 
<%: Html.EditorFor(m => m.RoleId) %> 
<%: Html.EditorFor(m => m.RoleName) %> 

Vous verrez quand vous faites une source de vue que votre HTML ressemble à ceci:

<input class="check-box" id="Roles_0__IsInRole" name="Roles[0].IsInRole" type="checkbox" value="true" /><input name="Roles[0].IsInRole" type="hidden" value="false" /> 
<input id="Roles_0__RoleId" name="Roles[0].RoleId" type="hidden" value="1" /> 
RoleName1<input id="Roles_0__RoleName" name="Roles[0].RoleName" type="hidden" value="RoleName1" /> 
<input class="check-box" id="Roles_1__IsInRole" name="Roles[1].IsInRole" type="checkbox" value="true" /><input name="Roles[1].IsInRole" type="hidden" value="false" /> 
<input id="Roles_1__RoleId" name="Roles[1].RoleId" type="hidden" value="2" /> 
RoleName2<input id="Roles_1__RoleName" name="Roles[1].RoleName" type="hidden" value="RoleName2" /> 

Cela est essentiel pour le modèle de liaison lorsque votre formulaire est posté. Nous avons utilisé DisplayValue = true pour le nom d'affichage, car nous avons besoin de l'entrée masquée pour la liaison du modèle de retour, mais elle doit être en lecture seule. pour le roleId, c'est une entrée cachée et aucune valeur n'est affichée à l'utilisateur. Voir this post pour plus d'informations sur le HiddenInput. Lorsque vous publiez ce dossier, le classeur de modèle intégré MVC s'assure que votre collection de rôles est une propriété construite et que l'état des cases à cocher est correctement reflété dans votre modèle.

+0

Votre Roles.ascx prend seulement le rôle, '<%: Html.EditorFor (m => m.Roles)%>' est une liste. Si je fais Roles.ascx prendre une liste, je dois faire une boucle dessus, alors il ne contient pas l'index du tableau dans la source de la vue. –

+1

En fait, c'est la beauté de celui-ci. Le <%: Html.EditorFor intégré (m => m.Roles)%> intégré est assez intelligent pour reconnaître qu'il est passé une collection. Ensuite, il voit le modèle d'éditeur Roles.ascx et l'utilise pour chaque élément de la collection. En effet, le modèle EditorFor() fait la boucle pour vous. Ça marche. J'ai mis en place votre exemple la nuit dernière et tout le code ci-dessus que j'ai posté provient de bits de travail. Essayez-le et vous verrez qu'il fonctionne selon vos besoins. –

0

Vous pouvez créer un classeur personnalisé. Lisez here pour un exemple.

+0

Comment est-ce que j'irais mettre 'AllRoles' sur la vue en tant que cases à cocher puis les obtenir dans le modèle sur le retour? –

Questions connexes