Rras
Rras

Reputation: 163

List of Users with roles in MVC Asp.net identity

I want to have list of all the users registered on my site with their roles.

Id | Name | Role


1 | ABC | Admin


2 | DEF | User

Something like this, I have made Roles controller in which all the roles is listed.

 public ActionResult Index()
    {
        var roles = context.Roles.ToList();
        return View(roles);
    }

In View

@model IEnumerable<Microsoft.AspNet.Identity.EntityFramework.IdentityRole>
@{
    ViewBag.Title = "Index";
}    
<div>
    @foreach (var role in Model)
    {
        <p>
            <strong>@role.Name | </strong>
        </p>
    }
</div>

This will list all the roles but i want user's list with their roles.

Please give any solution, Thanks

Upvotes: 13

Views: 37501

Answers (5)

Pistone Sanjama
Pistone Sanjama

Reputation: 561

Here's my solution to get a user with his/her role

Create a ViewModel to hold the users with the roles like below

public class UsersRoles
{
    public string UserId { get; set; }
    public string Username { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string PhoneNumber { get; set; }
    public string Email { get; set; }
    public string Role { get; set; }
}

In Controller: Select all the users like below using UserManager and put them in a variable

var users = _userManager.Users.ToList();

Create a empty list: one of userRoles and give it a name List usersRoles = new List();

Loop through all the users and while looping select all the roles using the role manager and passing it the user variable. If role is not null or empty(Here you have to make sure all users have a role assigned to them). Create a new userRole and fill it with the database values and then add it to the empty list you created above then you can return it however you want(usersRoles) and display it as IENumerable in your view and display the roles as Role.

       foreach (var user in users)

        {
            var roles = await _userManager.GetRolesAsync(user);

            var role = roles.FirstOrDefault();

            if(!string.IsNullOrEmpty(role))
            {
               var usersRole = new UsersRoles()
                {
                   UserId = user.Id,
                   Username = user.UserName,
                   Email = user.Email,
                   FirstName = user.FirstName,
                   LastName = user.LastName,
                   PhoneNumber = user.PhoneNumber,
                   Role = role
               };

                usersRoles.Add(usersRole);
            }

        }

Upvotes: 0

Ad Kahn
Ad Kahn

Reputation: 579

I also have a solution as above. This is a solution in MVC 6. the reason for this is i try the above code and faced problems. so..

lets start off Create a new class called UserViewModel. This will act as a view model for your page

public class UserViewModel
{
    public string Username { get; set; }
    public string Email { get; set; }
    public string RoleName { get; set; }
}

The controller is as follows:

public ActionResult Index()
    { 
       List<UserViewModel> modelLst = new List<UserViewModel>();
            var role = _db.Roles.Include(x => x.Users).ToList();

            foreach (var r in role)
            {
                foreach (var u in r.Users)
                {
                    var usr = _db.Users.Find(u.UserId);
                    var obj = new UserViewModel
                    {
                        Username = usr.FullName,
                        Email = usr.Email,
                        RoleName = r.Name
                    };
                    modelLst.Add(obj);
                }

            }
     return View(modelLst); 

    }

finally the view:

@model IEnumerable<ToroCRM.Models.UserViewModel>

<div class="row">
 @foreach (var r in Model.DistinctBy(x=>x.RoleName).ToList())
    {

        <h4>@r.RoleName</h4><hr />
        <table class="table">
        foreach (var user in Model.Where(x=>x.RoleName == r.RoleName))
         {
              <tr><th>@user.Username</th><td>@user.Email</td></tr> 
         }
        </table>

    }
</div>

Upvotes: 0

Zahir Firasta
Zahir Firasta

Reputation: 543

Although it is very late to answer this question, but here it is for the future visits:

Create view model class:

public class UserViewModel
{
    public string Username { get; set; }
    public string Email { get; set; }
    public string Role { get; set; }
}

Then populate this view model class in controller:

var usersWithRoles = (from user in context.Users
                      from userRole in user.Roles
                      join role in context.Roles on userRole.RoleId equals 
                      role.Id
                      select new UserViewModel()
                      {
                          Username = user.UserName,
                          Email = user.Email,
                          Role = role.Name
                      }).ToList();

Here, context.Users represents the AspNetUsers table which has a navigation property Roles which represents the AspNetUserInRoles table. Then we perform join of context.Roles which represents the AspNetRoles table to get the role name.

Now return this list to your Index view:

return View(userWithRoles);

In the view show the list of users with roles:

@model IEnumerable<MyProject.Models.UserViewModel>
<div class="row">
        <h4>Users</h4>

        @foreach (var user in Model)
        {
            <p>
                <strong>
                    @user.Username | @user.Email | @user.Role
                </strong>
            </p>
        }            
</div>

Edit: To get multiple roles of user(if assigned any)

var usersWithRoles = (from user in _ctx.Users
                     select new
                     {
                         Username = user.UserName,
                         Email = user.Email,
                         RoleNames = (from userRole in user.Roles
                                      join role in _ctx.Roles on userRole.RoleId equals role.Id
                                      select role.Name).ToList()
                     }).ToList().Select(p => new UserViewModel()

                     {
                         Username = p.Username,
                         Email = p.Email,
                         Role = string.Join(",", p.RoleNames)
                     });

Upvotes: 8

Armando Baltazar
Armando Baltazar

Reputation: 91

I have a solution as above.
This is a solution in MVC 6.

In AccountViewModel.cs add models

public class GroupedUserViewModel
{
    public List<UserViewModel> Users { get; set; }
    public List<UserViewModel> Admins { get; set; }
}
public class UserViewModel
{
    public string Username { get; set; }
    public string Email { get; set; }
    public string RoleName { get; set; }
}

the controller is as follows:

    public ActionResult Index()
    {            
        var role = (from r in context.Roles where r.Name.Contains("Adviser") select r).FirstOrDefault();            
        var users = context.Users.Where(x => x.Roles.Select(y => y.RoleId).Contains(role.Id)).ToList();

        var userVM = users.Select(user => new UserViewModel
        {
            Username = user.UserName,
            Email = user.Email,
            RoleName = "Adviser"
       }).ToList();


        var role2 = (from r in context.Roles where r.Name.Contains("Admin") select r).FirstOrDefault();
        var admins = context.Users.Where(x => x.Roles.Select(y => y.RoleId).Contains(role2.Id)).ToList();

        var adminVM = admins.Select(user => new UserViewModel
        {
            Username = user.UserName,
            Email = user.Email,
            RoleName = "Admin"
        }).ToList();


        var model = new GroupedUserViewModel { Users = userVM, Admins = adminVM };
        return View(model); 

    }

finally the view:

@model ToroCRM.Models.GroupedUserViewModel
<div class="row">
        <h4>Users</h4>
        @foreach (var user in Model.Users)
        {
            <p>
                <strong>
                    @user.Username <br />
                    @user.Email<br />
                    @user.RoleName
                </strong>
            </p>
        }
        <h4>Advisers</h4>
        @foreach (var usera in Model.Admins)
        {
            <p>
                <strong>
                    @usera.Username <br />
                    @usera.Email<br />
                    @usera.RoleName
                </strong>
            </p>
        }
</div>

Upvotes: 5

Imran Rashid
Imran Rashid

Reputation: 1338

Create a new class called UserViewModel. This will act as a view model for your page.

public class GroupedUserViewModel
{
    public List<UserViewModel> Users {get; set;}
    public List<UserViewModel> Admins {get; set;}
}

public class UserViewModel
{
    public string Username {get; set;}
    public string Roles {get; set;}
}

In the controller's action method, get the list of users along with their roles and map that to the UserViewModel.

public ActionResult Index()
{
    var allusers = context.Users.ToList();
    var users = allusers.Where(x=>x.Roles.Select(role => role.Name).Contains("User")).ToList();
    var userVM = users.Select(user=>new UserViewModel{Username = user.FullName, Roles = string.Join(",", user.Roles.Select(role=>role.Name))}).ToList();

    var admins = allusers.Where(x=>x.Roles.Select(role => role.Name).Contains("Admin")).ToList();
    var adminsVM = admins.Select(user=>new UserViewModel{Username = user.FullName, Roles = string.Join(",", user.Roles.Select(role=>role.Name))}).ToList(); 
    var model = new GroupedUserViewModel{Users = userVM, Admins = adminsVM};

    return View(model);
}

Then use the new model in the view. Make sure to use correct namespace here where you defined your view model.

@model Models.GroupedUserViewModel
@{
    ViewBag.Title = "Index";
}    
<div>
    @foreach (var user in Model.Admins)
    {
        <p>
            <strong>@user.Username | @user.Roles </strong>
        </p>
    }

    @foreach (var user in Model.Users)
    {
        <p>
            <strong>@user.Username | @user.Roles </strong>
        </p>
    }
</div>

Upvotes: 12

Related Questions