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:

[codesyntax lang=”csharp”]

    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; }
    }

[/codesyntax]

Now we need our Actions:

[codesyntax lang=”csharp”]

        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();
        }

[/codesyntax]

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

[codesyntax lang=”csharp”]

@model WebUI.ViewModel.UserRoleViewModel

@using (Html.BeginForm("EditUserRole", "Administrator"))
{
    @Html.HiddenFor(x => Model.UserId)

    @Html.EditorFor(x => Model.Roles)

    <input type="submit" />
}

[/codesyntax]

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.

[codesyntax lang=”csharp”]

@model WebUI.ViewModel.RoleViewModel

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

[/codesyntax]

And thats it. No explanation needed.