.NET Core 2.1 Identity为所有用户提供相关角色
我正在尝试为用户管理管理页面提取所有Identity用户及其相关角色。 我认为这将相当容易,但显然不是。 我尝试过以下解决方案: https : //stackoverflow.com/a/43562544/5392786但到目前为止还没有解决。
这是我到目前为止:
ApplicationUser:
public class ApplicationUser : IdentityUser { public List<IdentityUserRole> Roles { get; set; } }
的DbContext
public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext(DbContextOptions options) : base(options) { } }
启动标识代码
services.AddIdentity(options => options.Stores.MaxLengthForKeys = 128) .AddEntityFrameworkStores() .AddDefaultTokenProviders();
我要显示列表的Razor页面:
public class IndexModel : PageModel { private readonly UserManager userManager; public IndexModel(UserManager userManager) { this.userManager = userManager; } public IEnumerable Users { get; set; } public void OnGetAsync() { this.Users = userManager.Users.Include(u => u.Roles).ToList(); } }
调用userManager.Users.Include(u => u.Roles).ToList();
时,我收到以下错误userManager.Users.Include(u => u.Roles).ToList();
:
MySql.Data.MySqlClient.MySqlException:’字段列表’中的’未知列’u.Roles.ApplicationUserId’
我现在已经实现了以下解决方案。
正如CodeNotFound在评论中指出的那样,IdentityUser曾经拥有一个Roles
属性。 在.NET Core中不再是这种情况。 GitHub上的这个评论/问题似乎是.Net Core的当前解决方案。 我试图用以下代码实现它:
ApplicationUser
public class ApplicationUser : IdentityUser { public ICollection UserRoles { get; set; } }
ApplicationUserRole
public class ApplicationUserRole : IdentityUserRole { public virtual ApplicationUser User { get; set; } public virtual ApplicationRole Role { get; set; } }
ApplicationRole
public class ApplicationRole : IdentityRole { public ICollection UserRoles { get; set; } }
的DbContext
public class ApplicationDbContext : IdentityDbContext, ApplicationUserRole, IdentityUserLogin, IdentityRoleClaim , IdentityUserToken > { public ApplicationDbContext(DbContextOptions options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); builder.Entity(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(); }); } }
启动
services.AddIdentity(options => options.Stores.MaxLengthForKeys = 128) .AddEntityFrameworkStores() .AddDefaultTokenProviders();
最后,确保在使用它时,您急切地加载用户的UserRoles,然后是UserRole的角色,如下所示:
this.Users = userManager.Users.Include(u => u.UserRoles).ThenInclude(ur => ur.Role).ToList();
我有一个问题,其中每个UserRole
的Role
属性为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
参考评论
首先是获取数据的代码
public async Task> 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> Users { get; set; } public virtual ICollection> 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().HasMany(u => u.Claims).WithOne().HasForeignKey(c => c.UserId).IsRequired().OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity ().HasMany(u => u.Roles).WithOne().HasForeignKey(r => r.UserId).IsRequired().OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity().HasMany(r => r.Claims).WithOne().HasForeignKey(c => c.RoleId).IsRequired().OnDelete(DeleteBehavior.Cascade); modelBuilder.Entity ().HasMany(r => r.Users).WithOne().HasForeignKey(r => r.RoleId).IsRequired().OnDelete(DeleteBehavior.Cascade); modelBuilder.EnableAutoHistory(null); }
结果将是用户名和用户角色。 如果用户拥有多个角色,则数据将显示为此管理员,编辑器等…
完整的代码可以在这里找到 这里和这里希望这个帮助。
- ASP.NET 5中Global.json中项目部分的说明
- 托管ASP.NET Core作为Windows服务
- 如何正确地在MVC6中注入HttpContext
- 如何在ASP.NET Core中设置强类型配置?
- OpenIdConnectAuthenticationHandler:message.State为null或为空
- 如何将.xproj引用到.csproj?
- 调用AddAuthorization是不明确的
- 如何从.net核心中的appsettings.json中提取列表
- .NET Core IServiceScopeFactory.CreateScope()vs IServiceProvider.CreateScope()扩展