Reputation: 45
I have organizations as clients. Under each organization there are several users. In the view, when an organization is selected from a dropdown list, users under that specific organization are updated from database using Ajax. When I post the model, the users list is null. I tried several options, but nothing seems to work. This is a simplified version of the final code I have.
public class AccessModel
{
public List<Organization> AllOrganizations { get; set; }
public List<UserModel> Users { get; set; }
//and several other properties
}
My Get Action
[HttpGet]
public ActionResult GrantAccess()
{
var model = new AccessModel();
model.AllOrganizations = db.Organizations.ToList();
return View(model);
}
My View
@model MyModels.AccessModel
@using (Html.BeginForm("GrantAccess", "Access", FormMethod.Post))
{
<div>
@Html.DropDownList("Organizations", new SelectList(Model.AllOrganizations, "Id", "Name"),
"choose", new { htmlAttributes = new { @onchange = "getUsers(this.value)" })
</div>
<div id="Users">
@{Html.RenderPartial("_UsersList", Model.Users);}
</div>
}
My Jquery
<script>
function getUsers(str) {
$("#Users").load('@(Url.Action("ReturnUsers", "Product", null))?orgNumber=' + str);
}
</script>
My Action that renders the Partial page when called from Ajax
public ActionResult ReturnUsers(int orgNumber)
{
var usersList= db.Users.Where(u => u.OrganizationId == orgNumber).ToList();
var model= new AccessModel();
model.Users = usersList;
return PartialView("_UsersList", model);
}
The Partial page _UsersList.cshtml
@model AccessModel
@if (Model.Users != null)
{
foreach (var item in Model.Users)
{
<fieldset>
@Html.HiddenFor(modelItem => item.User.Id)
@Html.CheckBoxFor(modelItem => item.isSelected)
@Html.DisplayFor(modelItem => item.User.LastName)
@Html.DisplayFor(modelItem => item.User.FirstName)
</fieldset>
}
}
And finaly, The Post Action
[HttpPost]
public ActionResult GrantAccess(AccessModel model)
{
//here model.Users is null!
}
The view displays the users alright, only the values are not passed to my Post Model. Any suggestions?
Upvotes: 1
Views: 103
Reputation: 33306
If you use a for
loop instead of a foreach
the name attribute is rendered in a format that the model binder can pickup.
@model AccessModel
@if (Model.Users != null)
{
@for (var i = 0; i < Model.Users.Count; i++)
{
<fieldset>
@Html.HiddenFor(modelItem => Model.Users[i].Id)
@Html.CheckBoxFor(modelItem => Model.Users[i].isSelected)
@Html.DisplayFor(modelItem => Model.Users[i].LastName)
@Html.DisplayFor(modelItem => Model.Users[i].FirstName)
</fieldset>
}
}
Upvotes: 2