2016-05-26 12 views
1

Ich erstelle eine Roles/Permissions-Komponente für meine Anwendung. Meine Rolle View-Modell sieht wie folgt aus:DropDownListFor Composite Key mit Wertspalte

public class RoleView 
{ 
    public int Id { get; set; } 

    public ApplicationWithPermissionsView Application { get; set; } 

    public List<RolePermissionView> Permissions { get; set; } 

    public IEnumerable<KeyValuePair<string, int>> PermissionValues 
    { 
     get 
     { 
      return EnumHelper.ToList<PermissionValue>(); 
     } 
    } 

    [Required] 
    public string Name { get; set; } 
} 

Die RolePermission View-Modell wie folgt aussieht:

public class RolePermissionView 
{ 
    public int PermissionId { get; set; } 

    public int RoleId { get; set; } 

    public PermissionValue Value { get; set; } 
} 

PermissionValue ist eine Enumeration, die Mitglieder NotSet, Zulassen, Abweisen und speichert einen int-Wert in der hat Datenbank.

Wenn ich zu einer Rollenbearbeitungsseite gehe, zeige ich eine Liste von Berechtigungskategorien an, die jeweils eine Liste von Berechtigungen mit den entsprechenden Werten (RolePermission) für jede Berechtigung für diese Rolle haben. Wie Sie sehen können, verfügt RolePermissionView über zusammengesetzte Schlüssel (PermissionId, RoleId).

Wie kann ich eine Dropdownliste erstellen, die eine Liste möglicher Berechtigungswerte anzeigt und den richtigen Berechtigungswert für diese bestimmte Berechtigung auswählt?

Im Folgenden werden die Dropdown-Listen generiert, jedoch keine Werte ausgewählt. Außerdem wird nicht jeder Dropdown-Liste ein eindeutiger Name oder eine eindeutige ID zugewiesen, sodass die Bindung definitiv nicht funktioniert. Ich nehme an, wenn ich das später in ein Editor Template verschiebe, werden sie Unikate haben.

@foreach (var permission in category.Permissions) 
{    
<tr>       
    <td>@permission.Description</td>       
    <td>@Html.DropDownListFor(m => m.Permissions.Find(p => p.PermissionId == permission.Id).PermissionValue, new SelectList(Model.PermissionValues, "Value", "Key"))</td> 
</tr>    
} 

Antwort

0

Das Problem hier ist meist syntaktisch. Denken Sie daran, dass Sie für Dinge wie DropDownListFor und die anderen *For-Stil Helfer geben Sie eine Ausdruck, keine literale Instanz von etwas. Der Helfer versucht dann, diesen Ausdruck zu analysieren, um einen Namensattributwert für die Eingabe zu erstellen, der (hoffentlich) bindet, wenn die Daten zurückgesendet werden. Offensichtlich funktioniert dann etwas wie Find nicht, weil es keine Möglichkeit gibt, das zu übersetzen, so dass das Gleiche nach dem Posten am anderen Ende passiert. Stattdessen sollten Sie etwas tun:

@for (var i = 0; i < category.Permissions.Count(); i++) 
{ 
    <tr>       
     <td>@category.Permissions[i].Description</td>       
     <td>@Html.DropDownListFor(m => category.Permissions[i].PermissionValue, Model.PermissionValues)</td> 
    </tr> 
} 

Nun ist der Ausdruck konkret genug zu binden.

Ändern Sie auch Ihre Eigenschaft zu IEnumerable<SelectListItem> anstatt KeyValuePair zu verwenden. Dann müssen Sie kein SelectList manuell erstellen, was Ihnen viele mögliche Kopfschmerzen erspart. Um die Value der SelectListItem zu konstruieren, würde ich einfach die beiden zusammengesetzten IDs als Zeichenfolgen anhängen (da der Wert sowieso eine Zeichenfolge sein muss). Verbinden Sie sie mit einem Trennzeichen wie ein Komma. Anschließend können Sie den Posted-Wert abrufen und durch das gleiche Trennzeichen teilen, um Ihre beiden IDs zurückzubekommen. Natürlich müssen Sie sie dann beide zurück in int s konvertieren. Sie können nur einen Wert von einer Auswahl zurückgeben, also ist dies wirklich Ihre einzige Option, wenn es um zusammengesetzte Schlüssel geht.

+0

Danke für die Antwort. Ich habe mir einen ähnlichen Ansatz angesehen. Eine Sache zu beachten ist, dass category.Permissions einfach eine Liste von Berechtigungen für eine bestimmte Kategorie ist. Model.Permissions ist eine Liste von PermissionRoles (die zusammengesetzten Schlüssel) für die Rolle. Also wird das obige nicht für mich funktionieren. Das KeyValuePair war, weil ich eine nützlichere Liste von einem enum erzeugte. – getoutofmylaboratory

+0

Gespielt mit diesem für ein bisschen und es zeigt mindestens die Werte, gibt eindeutige Namen und wählt einen ausgewählten Wert (obwohl ich den dritten Parameter "objectSelected" der SelectList ausfüllen musste). Ich werde das für jetzt einen Sieg nennen. – getoutofmylaboratory