首页 文章

.NET Core 2.1 Identity为所有用户提供相关角色

提问于
浏览
11

我已经尝试过以下解决方案:https://stackoverflow.com/a/43562544/5392786但到目前为止还没有解决 .

这是我到目前为止:

ApplicationUser:

public class ApplicationUser : IdentityUser
{
    public List<IdentityUserRole<string>> Roles { get; set; }
}

DBContext

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
        : base(options)
    {
    }
}

Startup Identity code

services.AddIdentity<ApplicationUser, IdentityRole>(options => options.Stores.MaxLengthForKeys = 128)
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();

Razor Page where I want to display the list:

public class IndexModel : PageModel
{
    private readonly UserManager<ApplicationUser> userManager;

    public IndexModel(UserManager<ApplicationUser> userManager)
    {
        this.userManager = userManager;
    }

    public IEnumerable<ApplicationUser> Users { get; set; }

    public void OnGetAsync()
    {
        this.Users = userManager.Users.Include(u => u.Roles).ToList();
    }
}

调用 userManager.Users.Include(u => u.Roles).ToList(); 时出现以下错误:

MySql.Data.MySqlClient.MySqlException:'字段列表'中的'未知列'u.Roles.ApplicationUserId'

4 回答

  • -1

    我现在已经实现了以下解决方案 .

    正如CodeNotFound在评论中指出的那样,IdentityUser曾经有一个 Roles 属性 . 在.NET Core中不再是这种情况 . 这个comment/issue在GitHub上似乎是.Net Core的当前解决方案 . 我试图用以下代码实现它:

    ApplicationUser

    public class ApplicationUser : IdentityUser
    {
        public ICollection<ApplicationUserRole> UserRoles { get; set; }
    }
    

    ApplicationUserRole

    public class ApplicationUserRole : IdentityUserRole<string>
    {
        public virtual ApplicationUser User { get; set; }
        public virtual ApplicationRole Role { get; set; }
    }
    

    ApplicationRole

    public class ApplicationRole : IdentityRole
    {
        public ICollection<ApplicationUserRole> UserRoles { get; set; }
    }
    

    DBContext

    public class ApplicationDbContext
        : IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserClaim<string>,
        ApplicationUserRole, IdentityUserLogin<string>,
        IdentityRoleClaim<string>, IdentityUserToken<string>>
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }
    
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
    
            builder.Entity<ApplicationUserRole>(userRole =>
            {
                userRole.HasKey(ur => new { ur.UserId, ur.RoleId });
    
                userRole.HasOne(ur => ur.Role)
                    .WithMany(r => r.UserRoles)
                    .HasForeignKey(ur => ur.RoleId)
                    .IsRequired();
    
                userRole.HasOne(ur => ur.User)
                    .WithMany(r => r.UserRoles)
                    .HasForeignKey(ur => ur.UserId)
                    .IsRequired();
            });
        }
    }
    

    Startup

    services.AddIdentity<ApplicationUser, ApplicationRole>(options => options.Stores.MaxLengthForKeys = 128)
                .AddEntityFrameworkStores<ApplicationDbContext>()
                .AddDefaultTokenProviders();
    

    最后,确保当你使用它时,你急切地加载用户的UserRoles,然后像UserRole的角色一样:

    this.Users = userManager.Users.Include(u => u.UserRoles).ThenInclude(ur => ur.Role).ToList();
    

    我有一个问题,其中每个 UserRoleRole 属性为null,这是通过添加 .ThenInclude(ur => ur.Role) 部分解决的 .

    Microsoft doc on multi-level eager loading:https://docs.microsoft.com/en-us/ef/core/querying/related-data#including-multiple-levels

    ASP Core 2.2 update

    来自 IdentityUserRole<Guid> 不是字符串您可能还需要删除模型构建器中的代码才能使迁移工作 .

  • 0

    循环遍历用户列表并通过调用_userManager.GetRolesAsync(user)函数获取用户角色,并通过“,”在一个字符串变量中循环使用用户和拆分角色的角色

    [HttpPost]
        public async Task<IActionResult> OnPostGetPagination()
        {
    
    
            var users = await _userManager.Users.ToListAsync();
            InputModel inputModel = new InputModel();
            foreach (var v in users)
            {
                inputModel = new InputModel();
                var roles = await _userManager.GetRolesAsync(v);
                inputModel.Email = v.UserName;
                inputModel.role = "";
                foreach (var r in roles)
                {
                    if (!inputModel.role.Contains(","))
                    {
                        inputModel.role = r;
                    }
                    else
                    {
                        inputModel.role = "," + r;
                    }
                }
                Input2.Add(inputModel);
            }
    
    
        }
    

    祝好运

  • 1

    参考comment

    首先是获取数据的代码

    public async Task<IEnumerable<AccountViewModel>> GetUserList()
            {
                var userList = await (from user in _context.Users
                                      select new
                                      {
                                          UserId = user.Id,
                                          Username = user.UserName,
                                          user.Email,
                                          user.EmailConfirmed,
                                          RoleNames = (from userRole in user.Roles //[AspNetUserRoles]
                                                       join role in _context.Roles //[AspNetRoles]//
                                                       on userRole.RoleId
                                                       equals role.Id
                                                       select role.Name).ToList()
                                      }).ToListAsync();
    
                var userListVm = userList.Select(p => new AccountViewModel
                {
                    UserId = p.UserId,
                    UserName = p.Username,
                    Email = p.Email,
                    Roles = string.Join(",", p.RoleNames),
                    EmailConfirmed = p.EmailConfirmed.ToString()
                });
    
                return userListVm;
            }
    

    在ASP.Net核心2.1中,我们像这样设置ApplicationRole以获得用户的角色 . 您需要定义要显式公开的数据供用户使用

    public class ApplicationRole : IdentityRole
        {
            public virtual ICollection<IdentityUserRole<string>> Users { get; set; }
    
            public virtual ICollection<IdentityRoleClaim<string>> Claims { get; set; }
        }
    

    最后

    protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                base.OnModelCreating(modelBuilder);
    
                foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
                {
                    relationship.DeleteBehavior = DeleteBehavior.Restrict;
                }
    
                modelBuilder.Entity<User>().HasMany(u => u.Claims).WithOne().HasForeignKey(c => c.UserId).IsRequired().OnDelete(DeleteBehavior.Cascade);
                modelBuilder.Entity<User>().HasMany(u => u.Roles).WithOne().HasForeignKey(r => r.UserId).IsRequired().OnDelete(DeleteBehavior.Cascade);
    
                modelBuilder.Entity<ApplicationRole>().HasMany(r => r.Claims).WithOne().HasForeignKey(c => c.RoleId).IsRequired().OnDelete(DeleteBehavior.Cascade);
                modelBuilder.Entity<ApplicationRole>().HasMany(r => r.Users).WithOne().HasForeignKey(r => r.RoleId).IsRequired().OnDelete(DeleteBehavior.Cascade);
    
                modelBuilder.EnableAutoHistory(null);
            }
    

    结果将是用户名和用户角色 . 如果用户有多个角色,则数据将显示为此管理员,编辑器等...

    完整的代码可以在这里找到here herehere希望这个帮助 .

  • 34

    我通过创建一个包含我需要的所有列(包括角色)的视图并将其添加到上下文中来解决这个问题 .

相关问题