I am trying to create a table that lists the users in the system and their role. I keep running into a problem where its saying the model is null. I am quite new to asp so I think the value I set arent actually pulling values and why the view is crashing, but I have no idea why. I think this is like the last little piece of ASP I cant seem to wrap around.
My Controller
public class UserRolesController : Controller
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly RoleManager<IdentityRole> _roleManager;
public UserRolesController(UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager)
{
_roleManager = roleManager;
_userManager = userManager;
}
public async Task<IActionResult> Administration()
{
var users = await _userManager.Users.ToListAsync();
var userRolesViewModel = new List<UserRolesViewModel>();
foreach (ApplicationUser user in users)
{
var thisViewModel = new UserRolesViewModel();
thisViewModel.UserId = user.Id;
thisViewModel.Email = user.Email;
thisViewModel.FirstName = user.FirstName;
thisViewModel.LastName = user.LastName;
thisViewModel.Roles = await GetUserRoles(user);
userRolesViewModel.Add(thisViewModel);
}
return View(userRolesViewModel);
}
private async Task<List<string>> GetUserRoles(ApplicationUser user)
{
return new List<string>(await _userManager.GetRolesAsync(user));
}
public async Task<IActionResult> Manage(string userId)
{
ViewBag.userId = userId;
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
{
ViewBag.ErrorMessage = $"User with Id = {userId} cannot be found";
return View("NotFound");
}
ViewBag.UserName = user.UserName;
var model = new List<ManageUserRolesViewModel>();
foreach (var role in _roleManager.Roles.ToList())
{
var userRolesViewModel = new ManageUserRolesViewModel
{
RoleId = role.Id,
RoleName = role.Name
};
if (await _userManager.IsInRoleAsync(user, role.Name))
{
userRolesViewModel.Selected = true;
}
else
{
userRolesViewModel.Selected = false;
}
model.Add(userRolesViewModel);
}
return View(model);
}
[HttpPost]
public async Task<IActionResult> Manage(List<ManageUserRolesViewModel> model, string userId)
{
var user = await _userManager.FindByIdAsync(userId);
if (user == null)
{
return View();
}
var roles = await _userManager.GetRolesAsync(user);
var result = await _userManager.RemoveFromRolesAsync(user, roles);
if (!result.Succeeded)
{
ModelState.AddModelError("", "Cannot remove user existing roles");
return View(model);
}
result = await _userManager.AddToRolesAsync(user, model.Where(x => x.Selected).Select(y => y.RoleName));
if (!result.Succeeded)
{
ModelState.AddModelError("", "Cannot add selected roles to user");
return View(model);
}
return RedirectToAction("Administration");
}
}
My User Model
public class UserRolesViewModel
{
public string UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public IEnumerable<string> Roles { get; set; }
}
My Role Model
public class ManageUserRolesViewModel
{
public string RoleId { get; set; }
public string RoleName { get; set; }
public bool Selected { get; set; }
}
And my View where the program crashes on the foreach statement
@{
ViewData["Title"] = "Administration";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>User Roles</h1>
<table class="table table-striped">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Roles</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@foreach (var user in Model)
{
<tr>
<td>@user.FirstName</td>
<td>@user.LastName</td>
<td>@user.Email</td>
<td>@string.Join(" , ", user.Roles.ToList())</td>
<td>
<a class="btn btn-primary" asp-controller="UserRoles" asp-action="Manage" asp-route-userId="@user.UserId">Manage Roles</a>
</td>
</tr>
}
</tbody>
</table>