I\'m trying to configure role-based authorization in ASP.NET Identity. I want to make it so that Admin users can see a list of users and their roles (on the Index page) and
using System.Linq;
using System.Data;
using System.Data.Entity;
var db = new ApplicationDbContext();
var Users = db.Users.Include(u => u.Roles);
foreach (var item in Users)
{
string UserName = item.UserName;
string Roles = string.Join(",", item.Roles.Select(r=>r.RoleId).ToList());
}
IdentityUserRole
class have no navigation properties for IdentityUser
and IdentityRole
, just UserId
and RoleId
, its not that easy to get the roles of a user. So we need to use 2 db calls
var users = db.Users.Include(u => u.Roles);
var roles = db.Roles.Include(r => r.Users);
A ViewModel like this
public class UsersRolesViewModel
{
public List<ApplicationUser> Users { set; get; }
public List<IdentityRole> Roles { set; get; }
}
and the in View
@foreach (var user in Model.Users)
{
<tr class="index-item" data-href="@Url.Action("Details", "Users", new { id= user.Id })">
<td>
@user.Email
</td>
<td>
@string.Join(",", roles.Where(r => r.Users.Any(u => u.UserId == user.Id)).Select(r => r.Name))
</td>
<td class="index-links">
//stuff
</td>
</tr>
}
Edit
You can get all the data you want you with one query
var users = (from u in db.Users
let query = (from ur in db.Set<IdentityUserRole>()
where ur.UserId.Equals(u.Id)
join r in db.Roles on ur.RoleId equals r.Id select r.Name)
select new UserDto() {User = u, Roles = query.ToList<string>()})
.ToList();
Using this simple model
public class UserDto
{
public ApplicationUser User { set; get; }
public List<string> Roles { set; get; }
}
and the in View
@foreach (var user in Model.Users)
{
var appUser = user.ApplicationUser;
var roles = user.Roles;
<tr class="index-item" data-href="@Url.Action("Details", "Users", new { id= appUser.Id })">
<td>
@appUser.Email
</td>
<td>
@string.Join(",", roles)
</td>
<td class="index-links">
//stuff
</td>
</tr>
}