Thoughts, Codes and Articles. My Blog

Asp.net MVC Multiple check-boxes in an array or list

I had the problem of having a list of check-boxes being displayed in my view.

I’ll be using a scenario many of us are familiar with, Users and Roles. I’ll be using ASP.NET MCV 3 with the Razor view engine syntax.

Here is my ViewModel:

public class UserRoleViewModel
    {
        public UserRoleViewModel()
        {
            Roles = new List<RoleViewModel>();
        }
        public string UserId { get; set; }
        public List<RoleViewModel> Roles { get; set; }
    }
 
    public class RoleViewModel
    {
        public bool IsInRole { get; set; }
        [HiddenInput(DisplayValue = false)]
        public int RoleId { get; set; }
        [HiddenInput(DisplayValue = true)]
        public string RoleName { get; set; }
    }

Now we need our Actions:

public ActionResult EditUserRole(string userId)
        {
            var user = userService.GetUser(userId);
            var roles = userService.GetRoles();
 
            UserRoleViewModel viewModel = new UserRoleViewModel();
            viewModel.UserId = user.UserId;
            //Match the roles the user is in with the list of roles
            foreach (var role in roles)
            {
                viewModel.Roles.Add(new RoleViewModel
                                        {
                                            IsInRole = user.Roles.Any(r => r.RoleId == role.RoleId),
                                            RoleId = role.RoleId,
                                            RoleName = role.RoleName
                                        });
            }
 
            return View(viewModel);
        }
 
        [HttpPost]
        public ActionResult EditUserRole(UserRoleViewModel model)
        {
            List<Role> roles = model.Roles.Where(r => r.IsInRole).Select(r => new Role {RoleId = r.RoleId, RoleName = r.RoleName}).ToList();
            userService.AddRolesToUser(model.UserId, roles);
 
            return View();            
        }

Now we need to setup our view. This is our EditUserRole.cshtml

@model WebUI.ViewModel.UserRoleViewModel
 
@using (Html.BeginForm("EditUserRole", "Administrator"))
{
    @Html.HiddenFor(x => Model.UserId)
 
    @Html.EditorFor(x => Model.Roles)
 
    <input type="submit" />
}

This is our editor template, located at: ~/Shared/EditorTemplates/RoleViewModel.cshtml . Make sure the name of the file is the same name as the viewmodel you are sending.

@model WebUI.ViewModel.RoleViewModel
 
@Html.CheckBoxFor(m => m.IsInRole)
@Html.HiddenFor(m => m.RoleId)
@Html.LabelFor(m => m.IsInRole, Model.RoleName)
<br />

And thats it. No explanation needed.

Tagged with: ,
Posted in .Net Framework
11 comments on “Asp.net MVC Multiple check-boxes in an array or list
  1. Tim Cuculic says:

    I am looking for a simple example of MVC3 checkboxes. This looks great! Can you post a link to a working example so I can download and dissect in Visual Studio?

  2. Samant says:

    How does @Html.EditorFor(x=>Model.Roles) render the partial view for check boxes? It didn’t happen in mine. I explictly wrote @Html.Partial(“CheckBoxViewModel”,Model.Roles).
    Is this what we need to do?

  3. Shawn Mclean says:

    You need an editor template at: /Shared/EditorTemplates/RoleViewModel.cshtml. Make sure the name of the file is the same name as the viewmodel you are sending. This is how @Html.EditorFor(x=>Model.Roles) know to use that template.

  4. Allan Levsen says:

    Shawn, would you happen to know why in the POST the role name and the role id are not persisted (they are null) is the List of of RoleViewModel items… the IsSelected is correct and returned properly in the POST (EditUserRole)

    Allan

  5. Allan Levsen says:

    Sorry… I should note that I’m using MVC4 but that “shouldn’t” make a difference

  6. Allan Levsen says:

    LOL… Me again. I worked out the problem and thought I’d post it for others… my stupid mistake.

    I initially thought both the Id and the Role name were not being persisted when returning to the POST Action but it was just the RoleName that wasn’t – the Id was being persisted.

    I only needed to add a ‘@Html.HiddenFor(m => m.RoleName)’ in the EditorTemplate file in order to retain the name of the role : as follows.

    @model WebBoard.Web.Models.RoleViewModel

    @Html.CheckBoxFor(m => m.IsInRole)
    @Html.LabelFor(m => m.IsInRole, Model.rName)
    @Html.HiddenFor(m => m.RoleId)
    @Html.HiddenFor(m => m.RoleName)

    Thanks for the article – it was very helpful :)

  7. Hi,

    Thanks,it was a great article.

    How do we validate the roles checkbox list,so that at least one option is selected? Your help would be greatly appreciated.

  8. DanielHeth says:

    I kept having issues trying to add users to roles, then I realized you were not removing roles when i unchecked them. So I modified the [httppost] function slightly… more code and someone could make it look more efficient, but this works for me…

    List addRoles = new List();
    List removeRoles = new List();

    //this function retrieves my account view model and has a string[] Roles list
    AccountModel user = http://www.Controllers.AccountController.getAccount(UserName);

    bool addit;
    foreach (RoleModel rm in model.Roles) //loop through new roles
    {
    addit = rm.IsInRole;
    foreach (string roleName in user.Roles) //loop through existing roles
    {
    if (rm.Name == roleName)
    {
    if (addit)
    addit = false; //user already in this role
    else removeRoles.Add(roleName);
    break;
    }
    }

    if (addit) addRoles.Add(rm.Name);
    }

    if (addRoles.Count > 0) System.Web.Security.Roles.AddUserToRoles(UserName, addRoles.ToArray());
    if (removeRoles.Count > 0) System.Web.Security.Roles.RemoveUserFromRoles(UserName, removeRoles.ToArray());

  9. LNT says:

    I created editor template at /Shared/EditorTemplates/. But it’s not working. How should i do next? :(

  10. Jim Villani says:

    Excellent. Thank you. I learned about 6 things from this post.

  11. Shawn Mclean says:

    You’re welcome. I appreciate comments like these to know I am helping others.

Leave a Reply