我正在为我的应用程序构建角色/权限组件。我的角色视图模型如下所示:
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; }
}
RolePermission视图模型如下所示:
public class RolePermissionView
{
public int PermissionId { get; set; }
public int RoleId { get; set; }
public PermissionValue Value { get; set; }
}
PermissionValue是一个包含NotSet,Allow,Deny成员的枚举,并在数据库中存储一个int值。
如果我转到角色编辑页面,我会显示一个权限类别列表,每个权限类别都有一个权限列表,其中包含该角色的每个权限的相应值(RolePermission)。如您所见,RolePermissionView具有复合键(PermissionId,RoleId)。
如何构建下拉列表,该列表显示可能的权限值列表并为该特定权限选择正确的权限值?
以下内容会生成下拉列表,但不会选择任何值。此外,不会为每个下拉列表提供唯一的名称或ID,因此绑定肯定不会起作用。我假设如果我稍后将其移动到编辑器模板中,他们将具有唯一性。
@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>
}
答案 0 :(得分:0)
这里的麻烦主要是句法。请记住,对于像DropDownListFor
和其他*For
样式帮助者这样的事情,您要传递表达式,而不是某个文字实例。然后,帮助程序尝试解析该表达式,以在输入上创建名称属性值,该值将在发回数据时(希望)绑定。显然,做Find
这样的事情是行不通的,因为没有办法翻译它,以便在发布后在另一端发生同样的事情。相反,你应该做类似的事情:
@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>
}
现在,表达式足以绑定到。
另外,将PermissionValues
属性更改为IEnumerable<SelectListItem>
,而不是使用KeyValuePair
。然后,无需手动创建SelectList
,这将为您节省大量潜在的麻烦。要构造Value
的{{1}},我只需将两个复合id作为字符串附加(因为值必须是一个字符串)。像逗号一样用分隔符加入它们。然后,在帖子上,您可以获取已发布的值并将其拆分为相同的分隔符以使您的两个ID返回。显然,您还需要将它们转换回SelectListItem
s。你只能从一个选择中发回一个值,所以这是复合键的唯一选择。