如何显示具有角色的用户列表 - ASP.NET(核心)

Bra*_*ram 2 c# entity-framework asp.net-identity asp.net-core

我试图将每个用户的角色包含在列表中,如下图所示。在 Index 方法中,我想将用户加入角色并将其发送到视图。但由于某种原因user.Roles没有被认可。所以看起来导航属性是缺乏的。我在下面添加了屏幕截图以更清楚地说明我的问题。我一直在遵循几个指南,它们似乎都使用起来user.Roles没有任何问题。

该代码对我来说似乎是正确的,我在这里缺少什么吗?

在此输入图像描述

账户控制器

private AppIdentityDbContext context;

public AccountController(AppIdentityDbContext _context)
{
    context = _context;
}

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

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

    return View(usersWithRoles);
}
Run Code Online (Sandbox Code Playgroud)

用户视图模型

public class UsersViewModel
{
    public string Username { get; set; }
    public string Email { get; set; }
    public string Role { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

应用程序用户

public class ApplicationUser : IdentityUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

AppIdentityDbContext

public class AppIdentityDbContext : IdentityDbContext<ApplicationUser>
{
    public AppIdentityDbContext(DbContextOptions<AppIdentityDbContext> options)
        : base(options) { }
}
Run Code Online (Sandbox Code Playgroud)

应用程序数据库上下文

public class AppDbContext : DbContext
{

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(
            "Server=(localdb)\\MSSQLLocalDB;Database=Local;MultipleActiveResultSets=true");
    }
Run Code Online (Sandbox Code Playgroud)

我收到错误:

在此输入图像描述

Zhi*_* Lv 19

根据您的代码,您似乎正在将Asp.net Core Identity自定义用户数据和角色一起使用。

首先,请检查Startup.ConfigureServices方法,确保您已将Roles添加到ApplicationUser。像这样:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<ApplicationDbContext>(options =>
            options.UseSqlServer(
                Configuration.GetConnectionString("DefaultConnection")));

        services.AddIdentity<ApplicationUser, IdentityRole>(options => options.SignIn.RequireConfirmedAccount = true)
                 .AddDefaultUI()
                 .AddEntityFrameworkStores<ApplicationDbContext>()
                 .AddDefaultTokenProviders();

        //or using the following code.
        //services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
        //    .AddRoles<IdentityRole>()
        //    .AddEntityFrameworkStores<ApplicationDbContext>();

        services.AddControllersWithViews();
        services.AddRazorPages();

    }
Run Code Online (Sandbox Code Playgroud)

您可以参考这篇文章了解如何添加具有asp.net Core身份的角色。

然后,在控制器中,您可以使用UserManager.GetRolesAsync方法来获取指定用户所属的角色名称列表。代码如下:

public class ApplicationUserController : Controller
{
    private readonly UserManager<ApplicationUser> _userManager;

    private readonly ApplicationDbContext _context;
    public ApplicationUserController(UserManager<ApplicationUser> usermanager, ApplicationDbContext context)
    {
        _userManager = usermanager;
        _context = context;
    }
    public IActionResult Index()
    {
        var users = _userManager.Users.Select(c => new UsersViewModel()
        {
            Username = c.UserName,
            Email = c.Email,
            Role = string.Join(",", _userManager.GetRolesAsync(c).Result.ToArray())
        }).ToList();

        return View(users);
    }
}
Run Code Online (Sandbox Code Playgroud)

结果是这样的:

在此输入图像描述

此外,当使用Asp.net Identity时,数据库将使用AspNetUserRoles表来存储AspNetUsers表和AspNetRoles表之间的关系(您可以使用SQL Server Management Studio检查数据库表)。如果您不想使用 UserManager 来获取用户的角色,您可以加入 AspNetUsers、AspNetUserRoles 和 AspNetRoles 表并查询数据库并获取所需的属性。代码如下:

public class ApplicationUserController : Controller
{
    private readonly UserManager<ApplicationUser> _userManager;

    private readonly ApplicationDbContext _context;
    public ApplicationUserController(UserManager<ApplicationUser> usermanager, ApplicationDbContext context)
    {
        _userManager = usermanager;
        _context = context;
    }
    public IActionResult Index()
    { 
        var result = _context.Users
            .Join(_context.UserRoles, u => u.Id, ur => ur.UserId, (u, ur) => new { u, ur })
            .Join(_context.Roles, ur => ur.ur.RoleId, r => r.Id, (ur, r) => new { ur, r }) 
            .Select(c => new UsersViewModel()
            {
                Username = c.ur.u.UserName,
                Email = c.ur.u.Email,
                Role = c.r.Name
            }).ToList().GroupBy(uv=> new { uv.Username, uv.Email }).Select(r=> new UsersViewModel()
            {
                Username = r.Key.Username,
                Email = r.Key.Email,
                Role = string.Join(",", r.Select(c=>c.Role).ToArray())
            }).ToList();

        // you could also use the following code:
        var result2 = _context.Users
        .Join(_context.UserRoles, u => u.Id, ur => ur.UserId, (u, ur) => new { u, ur })
        .Join(_context.Roles, ur => ur.ur.RoleId, r => r.Id, (ur, r) => new { ur, r })
        .ToList()
        .GroupBy(uv => new { uv.ur.u.UserName, uv.ur.u.Email }).Select(r => new UsersViewModel()
        {
            Username = r.Key.UserName,
            Email = r.Key.Email,
            Role = string.Join(",", r.Select(c => c.r.Name).ToArray())
        }).ToList();

        return View(result);
    }
}
Run Code Online (Sandbox Code Playgroud)

通过使用上面的 linq 命令,我们也可以获得相同的结果。

在此输入图像描述

附加资源:

数据库上下文:

public class ApplicationDbContext : IdentityDbContext
{
    public DbSet<ApplicationUser> ApplicationUsers { get; set; }
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
    }
}

public class ApplicationUser: IdentityUser
{
    public int Age { get; set; }
    public string CustomTag { get; set; }
}
Run Code Online (Sandbox Code Playgroud)