Ich versuche, alle meine Identitätsbenutzer und ihre zugehörigen Rollen für eine Verwaltungsseite für die Benutzerverwaltung abzurufen. Ich dachte, das wäre einigermaßen einfach, aber anscheinend nicht. Ich habe folgende Lösung ausprobiert: https://stackoverflow.com/a/43562544/5392786 aber es hat bisher nicht geklappt.
Folgendes habe ich bisher:
Anwendungsbenutzer:
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-Identitätscode
services.AddIdentity<ApplicationUser, IdentityRole>(options => options.Stores.MaxLengthForKeys = 128)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
Rasierer Seite, auf der ich die Liste anzeigen möchte:
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();
}
}
Beim Aufrufen von userManager.Users.Include(u => u.Roles).ToList();
wird die folgende Fehlermeldung angezeigt:
MySql.Data.MySqlClient.MySqlException: 'Unbekannte Spalte' u.Roles.ApplicationUserId 'in' Feldliste ''
Ich habe jetzt die folgende Lösung implementiert.
Wie CodeNotFound in den Kommentaren feststellte, hatte IdentityUser früher eine Roles
-Eigenschaft. Dies ist in .NET Core nicht mehr der Fall. Dieses comment/issue auf GitHub scheint die aktuelle Lösung für .Net Core zu sein. Ich habe versucht, es mit folgendem Code zu implementieren:
Anwendungsbenutzer
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; }
}
Anwendungsrolle
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();
});
}
}
Anlaufen
services.AddIdentity<ApplicationUser, ApplicationRole>(options => options.Stores.MaxLengthForKeys = 128)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
Stellen Sie abschließend sicher, dass Sie bei der Verwendung die UserRoles des Benutzers und dann die Rolle des UserRole wie folgt laden:
this.Users = userManager.Users.Include(u => u.UserRoles).ThenInclude(ur => ur.Role).ToList();
Ich hatte ein Problem, bei dem die Role
-Eigenschaft jeder UserRole
null war und dies durch Hinzufügen des .ThenInclude(ur => ur.Role)
-Teils behoben wurde.
Microsoft-Dokument über mehrstufiges Ladenladen: https://docs.Microsoft.com/en-us/ef/core/querying/related-data#including-multiple-levels
durchläuft die Benutzerliste und erhält Benutzerrollen, indem die Funktion _userManager.GetRolesAsync (user) aufgerufen wird, und durchläuft Rollen von Benutzer- und geteilten Rollen mit "," in einer Stringvariablen
[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);
}
}
viel Glück
Referenz Kommentar
Erstens ist der Code zum Abrufen von Daten
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;
}
In ASP.Net Core 2.1 müssen Sie ApplicationRole wie folgt einrichten, um Rollen von Benutzern zu erhalten. Sie müssen Daten definieren, die der Benutzer explizit zur Verfügung stellen möchte
public class ApplicationRole : IdentityRole
{
public virtual ICollection<IdentityUserRole<string>> Users { get; set; }
public virtual ICollection<IdentityRoleClaim<string>> Claims { get; set; }
}
Endlich
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);
}
Das Ergebnis sind der Benutzername und die Benutzerrollen. Wenn der Benutzer mehr als eine Rolle hat, werden die Daten wie folgt angezeigt: Admin, Editor usw.
Den vollständigen Code finden Sie hier hierhier und hier Hoffe diese Hilfe.