wake-up-neo.com

.NET Core 2.1 Identity holt alle Benutzer mit ihren zugeordneten Rollen

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 ''

9
Andy Furniss

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

30
Andy Furniss

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 

1

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.

0