代码之家  ›  专栏  ›  技术社区  ›  ksliman

使用Blazor和实体框架的Asp.net标识6

  •  0
  • ksliman  · 技术社区  · 3 年前

    我在这方面遇到了困难,希望其他人能找到答案,我用Identity创建了一个Blazor应用程序,这就是我的 dbContext 看起来像:

    public class ApplicationDbContext : IdentityDbContext<AppUser, AppRole, string, 
        AppUserClaim,AppUserRole,AppUserLogin,AppRoleClaim,AppUserToken>
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }
    
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
           
            builder.Entity<AppUser>().ToTable("Users");
         
            builder.Entity<AppUser>().Property(x => x.FirstName).IsRequired();
            builder.Entity<AppUser>().Property(x => x.LastName).IsRequired();
            builder.Entity<AppUser>().Property(x => x.LastLoginDate);
            builder.Entity<AppUser>().HasMany(x => x.Roles).WithOne(x=>x.User).HasForeignKey(x=>x.UserId).IsRequired();
    
            builder.Entity<AppUserRole>().ToTable("UserRoles").HasOne(c => c.Role).WithMany(c => c.UserRoles).HasForeignKey(c => c.UserId);
    
            builder.Entity<AppRole>().ToTable("Roles");
            builder.Entity<AppRole>().Property(x => x.Description);
            builder.Entity<AppRole>().HasMany(x => x.UserRoles).WithOne(e => e.Role).HasForeignKey(ur => ur.RoleId).IsRequired();
            builder.Entity<AppRole>().HasMany(x => x.RoleClaims).WithOne(e=>e.Role).HasForeignKey(x=>x.RoleId).IsRequired();
            
            builder.Entity<AppRoleClaim>().ToTable("RoleClaims");
            builder.Entity<AppRoleClaim>().HasOne(x => x.Role);
    
            builder.Entity<AppUserClaim>().ToTable("UserClaims");            
        }
    }
    

    在我的 program.cs ,我有这个代码:

    builder.Services.AddIdentity<AppUser, AppRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>();
    builder.Services.AddTransient<RoleManager<AppRole>>();
    

    以下是我的身份类:

    public class AppRole:IdentityRole
    { 
        public string? Description { get; set; }
        public virtual ICollection<AppUserRole>? UserRoles { get; set; }
        public virtual ICollection<AppRoleClaim>? RoleClaims { get; set; }
    
        public AppRole()
        {
        }
    }
    
    public class AppRoleClaim : IdentityRoleClaim<string>
    {
        public virtual AppRole Role { get; set; }
    
        public AppRoleClaim()
        {
            Role = new AppRole();
        }
    }
    
    public class AppUser : IdentityUser
    {
        public string FirstName { get; set; } 
        public string LastName { get; set; }
        public DateTimeOffset? LastLoginDate { get; set; }
        public byte[]? Photo { get; set; }
        public virtual ICollection<AppUserRole> Roles { get; set; }
    
        public AppUser()
        {
            FirstName = "";
            LastName = "";
            Roles = new List<AppUserRole>(); 
        }
    }
    
    public class AppUserClaim : IdentityUserClaim<string>
    {
    }
    
    public class AppUserLogin : IdentityUserLogin<string>
    {
    }
    
    public class AppUserRole : IdentityUserRole<string>
    {
        public virtual AppUser User { get; set; }
        public virtual AppRole Role { get; set; }
    
        public AppUserRole()
        {
            User = new AppUser();
            Role = new AppRole();
        }
    }
    
    public class AppUserToken : IdentityUserToken<string>
    {
    }
    

    这是我的表格结构:

    enter image description here

    最后是我的问题,当我打电话的时候 UserManager.CreateAsync(NewUser) 用户是正确创建的,但是当我尝试将新创建的用户添加到一个角色(例如管理员角色)时 await UserManager.AddToRoleAsync(NewUser, "Admin"); 它不会抛出任何错误,但会创建一个具有null用户名、名字等的新用户,并向角色表中添加一个具有nullName和null规范化名称的新角色。然后它将该角色添加到 UserRoles 桌子所有这些都没有任何错误。

    根据MS文档,这应该创建一个新用户,并将该用户添加到管理员角色。我构建这个的文档在这里 https://learn.microsoft.com/en-us/aspnet/core/security/?view=aspnetcore-6.0

    0 回复  |  直到 3 年前
        1
  •  0
  •   ksliman    3 年前

    经过今天的挖掘,我发现了发生了什么。看看我的 AppUserRole 班

    public class AppUserRole : IdentityUserRole<string>
    {
        public virtual AppUser User { get; set; }
        public virtual AppRole Role { get; set; }
        public AppUserRole()
        {
            User = new AppUser();
            Role = new AppRole();
        }
    }
    

    因为我正在新建一个 AppUser() 和一个新的 AppRole() 它们依次调用基类构造函数,其中 IdentityRole 设置其 Id 属性转换为新的 Guid 当的构造函数 IdentityUser 被调用。我通过查看 AspNetCore.Identity 源代码。因此,EntityFramework正确地完成了它的工作,它看到了一个全新的 应用程序用户角色 有一个新的 身份用户 和新的 身份角色 由于这些是的导航属性 AppRole 它在数据库中创建了它们。

    太长,读不下去了 修复方法是使中的导航属性 应用程序用户角色 类可以为null,并且不能在构造函数中新建它们,如下所示:

    public class AppUserRole : IdentityUserRole<string>
    {
        public virtual AppUser? User { get; set; }
        public virtual AppRole? Role { get; set; }
        public AppUserRole()
        {
            
        }
    }