复选框MVC -组-用户

本文关键字:用户 -组 MVC 复选框 | 更新日期: 2023-09-27 18:12:11

我有数据库表用户和角色,我需要视图,显示我所有可用的角色,并检查了那些用户有。我已经有了显示所有可用角色的方法和显示用户拥有角色的方法,但我不知道如何在视图中实现那个,如何让那些复选框被选中。非常感谢您的帮助

表角色

[![1]][1]

所有可用角色的方法

[![2]][2]

所选角色的方法

[![3]][3]

模型
public class UserRoleModel
{
    public int ID { get; set; }     
    public int? UserID { get; set; }
    public UserRoleModel()
    {
        ListRole = new List<RoleVM>();
    }
    public string Name { get; set; }
    public List<RoleVM> ListRole { get; set; }
    public List<RoleVM> UserRole { get; set; }
}
public class RoleVM
{
    public int ID { get; set; }
    public string Name { get; set; }
    public bool IsSelected { get; set; }
}

带复选框的视图

@for(int i = 0; i < Model.ListRole.Count; i++)
{
    @Html.HiddenFor(m => m.ListRole[i].ID)
    @Html.CheckBoxFor(m => m.ListRole[i].IsSelected, new { @checked = "checked" }); 
    @Html.LabelFor(m => m.ListRole[i].IsSelected, Model.ListRole[i].Name)
}

复选框MVC -组-用户

在MVC和Razor中,复选框在有值时被选中,所以基本上你必须将正确的值附加到被选中的复选框上。

根据文档:

public static MvcHtmlString CheckBoxFor<TModel>(
    this HtmlHelper<TModel> htmlHelper,
    Expression<Func<TModel, bool>> expression
)

考虑到expression不是一个复选框值,而是模型绑定,所以我建议使用:

@Html.CheckBoxFor(m => m.ListRole[i]);

其中m.ListRole[i]表示模型中的布尔值

你可以在View中查看你的列表:

@for(int i = 0; i < Model.ListRole.Count; i++)
{
    if(Model.UserRole.Select(x => x.Name).Contains(Model.ListRole[i].Name))
    {
       @Html.HiddenFor(m => m.ListRole[i].ID)
       @Html.CheckBoxFor(m => m.ListRole[i].IsSelected, new { @checked = "checked" }); 
       @Html.LabelFor(m => m.ListRole[i].IsSelected, Model.ListRole[i].Name)
    }
    else
    {
       @Html.HiddenFor(m => m.ListRole[i].ID)
       @Html.CheckBoxFor(m => m.ListRole[i].IsSelected); 
       @Html.LabelFor(m => m.ListRole[i].IsSelected, Model.ListRole[i].Name)
    }
}

不能说这是最好的方法,但它会起作用。另一个机会是正确填充模型IsSelected字段。

你试过MVCCheckboxList吗?如果你可以使用这个库,它看起来像这样:

@Html.CheckBoxListFor(m => //string array that is bound to your model, will have selected options on POST
    m => //SelectList of all available items
    m => m.Value,
    m => m.Text,
    m => //collection of SelectListItem for all selected items,
    MvcCheckBoxList.Model.Position.Vertical,
    x => new { @class = "editor-cbl" })

首先你的数据库结构是不正确的,正如我在你之前的问题中所指出的。为了正确地表示这一点,您需要3个表,Users, RolesUserRoles,这是UsersRoles之间的多对多关系,并包含UserID (FK到Users表)和RoleID (FK到Roles表)的字段。

你已经表明你不准备改变这一点(意思是你甚至不能添加一个新角色,不能改变现有角色的名字等等),但至少你需要所有可用角色的一些表示。使用Distinct()查询现有角色无法工作,因为最初数据库将为空。你的模型不需要2个RoleVM集合(你唯一的编辑一个)。

首先需要根据所有角色创建RoleVM集合,然后根据用户当前的角色设置IsSelected属性。

您的GET方法需要类似于

public ActionResult Edit(int ID)
{
  // Get all roles
  IEnumerable<string> roles = new List<string>(){ "Administrator", "Gestor", "Supervisor", "SecurityManager", "Admin" };
  // Get the User
  User user = db.Users().Where(u => u.ID == ID).FirstOrDefault();
  // Get the user roles (if not included in User model
  IEnumerable<UserRole> userRoles = db.UserRoles().Where(r => r.UserID == ID);
  // Create collection of all roles
  List<RoleVM> allRoles = roles.Select(r => new RoleVM()
  {
    Name = r
  }).ToList();
  // Set the ID and IsSelected properties based on the user roles
  foreach(RoleVM role in allRoles)
  {
    UserRole userRole = userRoles.FirstOrDefault(r => r.Role == role.Name);
    if (userRole != null)
    {
      role.ID = userRole.ID;
      role.IsSelected = true;
    }
  }
  // Initialize the view model
  UserVM model = new UserVM()
  {
    ID = user.ID,
    Name = user.Name,
    Roles = allRoles
  };
  return View(model);
}

,在视图中,从CheckBoxFor()方法中删除new { @checked = "checked" }