使用 asp.net 6.0 Identity 在 razor 页面中列出具有角色的用户

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

我想创建一个列出所有用户及其相关角色的 Razor 页面。虽然我可以找到一些针对以前版本的 ASP.NET MVC 执行此操作的教程,但我无法使用 ASP.NET Core 6.0 Identity Razor 页面执行此操作。 目前,我有以下代码,但在导航到页面时收到错误消息

//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 class="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)

使用 Any() 函数检查模型是否包含数据,或者您可以添加微调器。

试试这个。

@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 class="table">
.
.rest of the code
.
.</table>

}

另一个解决方案是在页面加载数据时添加一个微调器,如下所示:

@{
    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 class="table">
.
.rest of the code
.
.</table>

}

请注意,在第二种解决方案中,您需要将微调器添加到 css

我这里写了一个简单的demo,大家可以参考一下

        [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
@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 />
}

结果