I have this model which I'm using in a view:
using (var db = new FieldSaverContext())
{
AspNetUser user = (from p in db.AspNetUsers
where p.Id == id
select p).Include(m => m.AspNetRoles) .First();
model.AUser = user;
List<AspNetRole> roles = (from r in db.AspNetRoles
select r).ToList();
model.RoleList = roles;
List<ListID> ids = (from l in db.ListIDs
select l).ToList();
model.ListIDList = ids;
List<ViewerList> viewerLists = (from v in db.ViewerList
select v).ToList();
model.ViewerList = viewerLists;
}
This is how my view looks like:
@using (Html.BeginForm("Edit", "Users"))
{
<div class="container containerEdit">
<div class="col-md-9">
<div class="col-md-6">
<div class="form-group">
@Html.LabelFor(m => m.AUser.Id)
<label>@Html.DisplayFor(m => m.AUser.Id)</label>
</div>
<div class="form-group">
@Html.DisplayFor(m => m.AUser.FirstName)
@Html.TextBoxFor(m => m.AUser.FirstName)
</div>
<div class="form-group">
@Html.LabelFor(m => m.AUser.PhoneNumber)
@Html.TextBoxFor(m => m.AUser.PhoneNumber)
</div>
<div class="form-group">
@Html.LabelFor(m => m.ListIDList)
@Html.DropDownListFor(n => n.ListIDList, new SelectList(Model.ListIDList, "ID", "Value"))
</div>
<div class="form-group">
@Html.LabelFor(m => m.AUser.Note1)
@Html.TextBoxFor(m => m.AUser.Note1)
</div>
<div class="form-group">
@Html.LabelFor(m => m.AUser.Note2)
@Html.TextBoxFor(m => m.AUser.Note2)
</div>
</div>
<div class="col-md-6">
<div class="form-group"> </div>
<div class="form-group">
@Html.LabelFor(m => m.AUser.LastName)
@Html.TextBoxFor(m => m.AUser.LastName)
</div>
<div class="form-group">
@Html.LabelFor(m => m.AUser.Email)
@Html.TextBoxFor(m => m.AUser.Email)
</div>
<div class="form-group">
<label>Report Viewer</label>
@Html.DropDownListFor(v => v.AUser.ViewerId, new SelectList(Model.ViewerList, "ID", "Value"))
</div>
</div>
@Html.HiddenFor(v => v.AUser.Id)
</div>
<div class="col-md-3">
@foreach (AspNetRole role in Model.RoleList)
{ @Html.CheckBox(role.Name, Model.AUser.AspNetRoles.Any(userRole => userRole.Id == role.Id)) @Html.Label(role.Name)<br /> }
</div>
</div>
<div class="col-md-8">
<input type="submit" class="btn btn-success btn-lg btnSaveEdit" value="Save" />
</div>
}
When the postback is happening, I'm able to get the values for the AUser but I'm not getting any of the values for the Model.RoleList which is used in checkbox. I want to check which checkboxes are checked from the RoleList and assign those roles to the User.
What am I missing?
Edit Action(s):
[HttpGet]
public ActionResult Edit(int? id)
{
ManageViewModel model = new ManageViewModel();
using (var db = new DbContext())
{
AspNetUser user = (from p in db.AspNetUsers
where p.Id == id
select p).Include(m => m.AspNetRoles) .First();
model.AUser = user;
List<AspNetRole> roles = (from r in db.AspNetRoles
select r).ToList();
model.RoleList = roles;
List<ListID> ids = (from l in db.ListIDs
select l).ToList();
model.ListIDList = ids;
List<ViewerList> viewerLists = (from v in db.ViewerList
select v).ToList();
model.ViewerList = viewerLists;
}
return View(model);
}
[HttpPost]
public ActionResult Edit(ManageViewModel model)
{
AspNetUser user = model.AUser;
using (var db = new DbContext())
{
AspNetUser dbUser = (from u in db.AspNetUsers
where u.Id == model.AUser.Id
select u).First();
dbUser.FirstName = model.AUser.FirstName;
dbUser.LastName = model.AUser.LastName;
dbUser.Email = model.AUser.Email;
dbUser.PhoneNumber = model.AUser.PhoneNumber;
dbUser.Note1 = model.AUser.Note1;
dbUser.Note2 = model.AUser.Note2;
dbUser.ViewerId = model.AUser.ViewerId;
db.SaveChanges();
}
return View();
}
The issue is that the roles are not bound to your view model. So here's what you have to do:
Create a new role view model:
public class RoleViewModel
{
public int Id { get; set; }
public string Name { get; set; }
public bool Selected { get; set; }
}
Modify your ManageUserViewModel
to have a list of RoleViewModel
instead of AspNetRole
:
public class ManageUserViewModel
{
public List<RoleViewModel> Roles { get; set;}
// Your other properties
}
Change your edit to set the Roles
property from the available roles:
public ActionResult Edit(int? id)
{
// beginning of your action
List<AspNetRole> roles = from r in db.AspNetRoles
select r;
model.Roles = new List<RoleViewModel>();
foreach(AspNetRole role in roles){
model.Roles.Add(new RoleViewModel {
Id = role.Id,
Name = role.Name,
Selected = user.AspNetRoles.Any(userRole => userRole.Id == role.Id)
});
}
// end of your action
}
Change your other action to
public ActionResult Edit(ManageViewModel model){
// beginning of your action
// remove roles from user
List<AspNetRoles> newRoles = new List<AspNetRoles>();
foreach(RoleViewModel role in model.Roles){
newRole.Add(db.AspNetRoles.Find(role.id))
}
// set your user roles from newRoles
// end of your action
}
In your view change the checkbox part by :
@Html.EditorFor(model => model.Roles)
And finally create a Shared/EditorTemplate/RoleViewModel.cshtml
file :
@model RoleViewModel
@Html.HiddenFor(model => model.Id)
@Html.CheckBoxFor(model => model.Selected)
@Html.DisplayFor(model => model.Name)