Home > OS >  List users with roles in a razor page using asp.net 6.0 Identity
List users with roles in a razor page using asp.net 6.0 Identity

Time:03-16

I would like to create a Razor Page which lists all users with their associated roles. While I could find some tutorials doing this for previous versions of ASP.NET MVC but I am not able to do this using ASP.NET Core 6.0 Identity Razor pages. Currently, I have the following code but I get an error message when navigating to the page

//UserRolesViewModel.cs file
namespace MyApp.Models
{
    public class UserRolesViewModel
    {
        public string UserName { get; set; }
        public string Email { get; set; }
        public IEnumerable<string> Roles { get; set; }
    }
}

//Index.cshtml.cs file
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using MyApp.Models;

namespace MyApp.Pages.Users
{
    public class IndexModel : PageModel
    {
        private readonly UserManager<IdentityUser> _userManager;
        private readonly RoleManager<IdentityRole> _roleManager;

        public IndexModel
            (
            UserManager<IdentityUser> userManager,
            RoleManager<IdentityRole> roleManager
            )
        {
            _userManager = userManager;
            _roleManager = roleManager;
        }
        public IList<UserRolesViewModel> UserRolesViewModel { get; set; }

        public async Task<IActionResult> OnGetAsync()
        {
            var users = await _userManager.Users.ToListAsync();
            var userRolesViewModel = new List<UserRolesViewModel>();
            foreach (IdentityUser user in users)
            {
                var thisViewModel = new UserRolesViewModel();
                thisViewModel.Email = user.Email;
                thisViewModel.Roles = await GetUserRoles(user);
                userRolesViewModel.Add(thisViewModel);
            }
            return Page();
        }
        private async Task<List<string>> GetUserRoles(IdentityUser user)
        {
            return new List<string>(await _userManager.GetRolesAsync(user));
        }
    }
}

//Index.cshtml file
@page
@model MyApp.Pages.Users.IndexModel

@{
    ViewData["Title"] = "Index";
    Layout = "~/Pages/Shared/_Layout.cshtml";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>
<table >
    <thead>
        <tr>
            <th>
                User
            </th>
            <th></th>
        </tr>
    </thead>
    <tbody>
@foreach (var item in Model.UserRolesViewModel) {
        <tr>
            @Html.DisplayFor(modelItem => item.Email)
        </tr>
        <td>@string.Join(" , ", item.Roles.ToList())</td>
}
    </tbody>
</table>


//Error message
NullReferenceException: Object reference not set to an instance of an object.
MyApp.Pages.Users.Pages_Users_Index.ExecuteAsync() in Index.cshtml
  @foreach (var item in Model.UserRolesViewModel)

CodePudding user response:

Use Any() function to check if the model holds data or you can add a spinner.

Try this out.

@page
@model MyApp.Pages.Users.IndexModel

@{
    ViewData["Title"] = "Index";
    Layout = "~/Pages/Shared/_Layout.cshtml";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>

if(Model.Any())
{
<table >
.
.rest of the code
.
.</table>

}

another solution is to add a spinner while the page loads the data like this :

@{
    ViewData["Title"] = "Index";
    Layout = "~/Pages/Shared/_Layout.cshtml";
}

<h1>Index</h1>

<p>
    <a asp-page="Create">Create New</a>
</p>

if(Model == null)
{ 
<div class = "spinner">
</div>
}
else{
<table >
.
.rest of the code
.
.</table>

}

please note that in the second solution you need to add spinner to your css

CodePudding user response:

I write a simple demo here, you can refer to it

        [BindProperty]
        public IList<UserRolesViewModel> model { get; set; } = new List<UserRolesViewModel>();

        public class UserRolesViewModel
        {
            public string UserName { get; set; }
            public string Email { get; set; }
            public IEnumerable<string> Roles { get; set; }
        }

        public async Task<IActionResult> OnGetAsync()
        {
            var users = await _userManager.Users.ToListAsync();
            
            foreach (IdentityUser user in users)
            {
                UserRolesViewModel urv = new UserRolesViewModel()
                {
                    UserName = user.UserName,
                    Email = user.Email,
                    Roles = await _userManager.GetRolesAsync(user)
                };

                model.Add(urv);
            }
            return Page();
        }

page

@page
@model IndexModel

@foreach (var item in Model.model) 
{
       <div>User: @item.UserName</div>
       <div>Email: @item.Email</div>
        @foreach (var role in item.Roles)
       {
           <div>Role: @role</div>
       }
       <br />
}

result

enter image description here

  • Related