Microsoft ASP.NET Identity - Multiple Users with the same name

后端 未结 2 746
面向向阳花
面向向阳花 2020-12-15 12:11

I\'m trying something quite exotic I believe and I\'m facing a few problems, which I hope can be solved with the help of the users here on StackOverflow.

The story<

2条回答
  •  春和景丽
    2020-12-15 12:43

    1st of all i understand the idea behind your thoughts, and as such i'll start to explain the "why" are you not able to create multiple users with the same name.

    The username with the same name: The problem you encounter right now is related to the IdentityDbContext. As you can see (https://aspnetidentity.codeplex.com/SourceControl/latest#src/Microsoft.AspNet.Identity.EntityFramework/IdentityDbContext.cs), the identityDbContext sets up rules about the unique users and roles, First on model creation:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            if (modelBuilder == null)
            {
                throw new ArgumentNullException("modelBuilder");
            }
    
            // Needed to ensure subclasses share the same table
            var user = modelBuilder.Entity()
                .ToTable("AspNetUsers");
            user.HasMany(u => u.Roles).WithRequired().HasForeignKey(ur => ur.UserId);
            user.HasMany(u => u.Claims).WithRequired().HasForeignKey(uc => uc.UserId);
            user.HasMany(u => u.Logins).WithRequired().HasForeignKey(ul => ul.UserId);
            user.Property(u => u.UserName)
                .IsRequired()
                .HasMaxLength(256)
                .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("UserNameIndex") { IsUnique = true }));
    
            // CONSIDER: u.Email is Required if set on options?
            user.Property(u => u.Email).HasMaxLength(256);
    
            modelBuilder.Entity()
                .HasKey(r => new { r.UserId, r.RoleId })
                .ToTable("AspNetUserRoles");
    
            modelBuilder.Entity()
                .HasKey(l => new { l.LoginProvider, l.ProviderKey, l.UserId })
                .ToTable("AspNetUserLogins");
    
            modelBuilder.Entity()
                .ToTable("AspNetUserClaims");
    
            var role = modelBuilder.Entity()
                .ToTable("AspNetRoles");
            role.Property(r => r.Name)
                .IsRequired()
                .HasMaxLength(256)
                .HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("RoleNameIndex") { IsUnique = true }));
            role.HasMany(r => r.Users).WithRequired().HasForeignKey(ur => ur.RoleId);
        }
    

    secondly on validate entity:

    protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry,
            IDictionary items)
        {
            if (entityEntry != null && entityEntry.State == EntityState.Added)
            {
                var errors = new List();
                var user = entityEntry.Entity as TUser;
                //check for uniqueness of user name and email
                if (user != null)
                {
                    if (Users.Any(u => String.Equals(u.UserName, user.UserName)))
                    {
                        errors.Add(new DbValidationError("User",
                            String.Format(CultureInfo.CurrentCulture, IdentityResources.DuplicateUserName, user.UserName)));
                    }
                    if (RequireUniqueEmail && Users.Any(u => String.Equals(u.Email, user.Email)))
                    {
                        errors.Add(new DbValidationError("User",
                            String.Format(CultureInfo.CurrentCulture, IdentityResources.DuplicateEmail, user.Email)));
                    }
                }
                else
                {
                    var role = entityEntry.Entity as TRole;
                    //check for uniqueness of role name
                    if (role != null && Roles.Any(r => String.Equals(r.Name, role.Name)))
                    {
                        errors.Add(new DbValidationError("Role",
                            String.Format(CultureInfo.CurrentCulture, IdentityResources.RoleAlreadyExists, role.Name)));
                    }
                }
                if (errors.Any())
                {
                    return new DbEntityValidationResult(entityEntry, errors);
                }
            }
            return base.ValidateEntity(entityEntry, items);
        }
    }
    

    The tip: What you can do to overcome this problem easilly, is, on the ApplicationDbContext that you currently have, override both these methods to overcome this validation

    Warning Without that validation you now can use multiple users with the same name, but you have to implement rules that stop you from creating users in the same customer, with the same username. What you can do is, adding that to the validation.

    Hope the help was valuable :) Cheers!

提交回复
热议问题