2

I can't figure out what I'm messing up. The FormCollection seems to show everything is right. RoleName comes back fine, too. So why is RoleMembership coming back null?

Model:

public class EditRoleMembershipViewModel
{
    public string RoleName { get; set; }
    public Dictionary<string, bool> RoleMembership { get; set; }
}

Controller Action:

[HttpGet]
public ActionResult EditRoleMembership(string roleName)
{
    var viewModel = new EditRoleMembershipViewModel {RoleName = roleName};

    var allUsers = _userServices.GetAllUsers();
    getRolesForUsers(allUsers);
    var role = _roleServices.GetRole(roleName);

    viewModel.RoleMembership = new Dictionary<string, bool>();
    foreach (var user in allUsers)
    {
        var isMember = user.Roles != null && user.Roles.Contains(role);
        viewModel.RoleMembership.Add(user.UserName, isMember);
    }

    return View(viewModel);
}

View:

@model CI.Portal.Mvc.ViewModels.EditRoleMembershipViewModel
@{
    ViewBag.Title = "Edit Role";
}
<h2>@ViewBag.Title: @Model.RoleName</h2>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
    <table>
        <thead>
            <tr>
                <th>
                </th>
                <th>
                    In Role
                </th>
            </tr>
        </thead>
        <tbody>
            @{
                int index = 0;
                foreach (var item in Model.RoleMembership)
                {
                    <tr>
                        <td>
                            @item.Key
                            @Html.Hidden(string.Format("model.RoleMembership[{0}].Key", index), item.Key)
                        </td>
                        <td>@Html.CheckBox(string.Format("model.RoleMembership[{0}].Value", index), item.Value)</td>
                    </tr>
                    index++;
                }
            }
        </tbody>
    </table>

    <p>
        <input type="submit" value="Save" />
    </p>
}
<div>
    @Html.ActionLink("Back to Details", "RoleDetails", new { Model.RoleName })
</div>
Jack Pines
  • 289
  • 4
  • 12

1 Answers1

3

Could you try removing the "model." prefix from the checkbox helper declaration.

Instead of

<td>
    @item.Key
    @Html.Hidden(string.Format("model.RoleMembership[{0}].Key", index), item.Key)
</td>
<td>
    @Html.CheckBox(string.Format("model.RoleMembership[{0}].Value", index), item.Value)
</td>

Do this:

<td>
    @item.Key
    @Html.Hidden(string.Format("RoleMembership[{0}].Key", index), item.Key)
</td>
<td>
    @Html.CheckBox(string.Format("RoleMembership[{0}].Value", index), item.Value)
</td>
mreyeros
  • 4,359
  • 20
  • 24
  • Unbelievable how simple that was. This is where coding by convention can really bite you in the rear. I'd happily give a bonus, if I knew how, if you would point me at a resource about the model-binder's conventions. – Jack Pines Jul 16 '12 at 17:45
  • here is a good SO post that has some resources covering model binding http://stackoverflow.com/questions/5692964/asp-net-mvc-3-model-binding-resources – mreyeros Jul 16 '12 at 18:09