从ASP.NET Identity 2.0.1中的角色中删除用户

时间:2014-07-20 11:10:41

标签: asp.net asp.net-mvc user-roles asp.net-identity-2

我定制了身份系统的一些功能以满足我的需求。

我有以下ApplicationUserManager:

public class ApplicationUserManager : UserManager<ApplicationUser, long>
{
    public ApplicationUserManager()
        : base(new UserStore<ApplicationUser, ApplicationRole,
            long, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>(new GestkatDbContext()))
    {
        //PasswordValidator = new MinimumLengthValidator(10);
    }

    public ApplicationUserManager(IUserStore<ApplicationUser,long> store)
        : base(store)
    {

    }

    public static ApplicationUserManager Create(
    IdentityFactoryOptions<ApplicationUserManager> options,
    IOwinContext context)
    {
        var manager = new ApplicationUserManager(
            new UserStore<ApplicationUser, ApplicationRole, long, ApplicationUserLogin,
                ApplicationUserRole,ApplicationUserClaim>(
                context.Get<GestkatDbContext>()));

        // Configure validation logic for usernames
        manager.UserValidator =
            new UserValidator<ApplicationUser,long>(manager)
            {
                AllowOnlyAlphanumericUserNames = false,
                //RequireUniqueEmail = true
            };


        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
        };


        // Configure user lockout defaults
        manager.UserLockoutEnabledByDefault = true;
        manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
        manager.MaxFailedAccessAttemptsBeforeLockout = 5;

        return manager;
    }

    public bool CreateUser(ApplicationUser user, string password)
    {
        var idResult = this.Create(user, password);
        return idResult.Succeeded;
    }

    public bool AddUserToRole(long userId, string roleName)
    {
        return this.AddToRole(userId, roleName).Succeeded;
    }

    public bool ClearAllUserRoles(long userId)
    {
        foreach (var role in this.GetRoles(userId))
        {
            if (!this.RemoveFromRole(userId, role).Succeeded)
            {
                return false;
            }
        }
        return true;
    }
}

其他自定义类是:

public class ApplicationUser : IdentityUser<long, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>
{
    public virtual UserInfo UserInfo { get; set; }

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(ApplicationUserManager manager)
    {
        // Note the authenticationType must match the one 
        // defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity =
            await manager.CreateIdentityAsync(this,
                DefaultAuthenticationTypes.ApplicationCookie);

        // Add custom user claims here
        return userIdentity;
    }

}

public class ApplicationRole : IdentityRole<long, ApplicationUserRole>
{
    public ApplicationRole() : base() { }
    public ApplicationRole(string name, string description)
    {
        this.Name = name;
        this.Description = description;
    }
    public virtual string Description { get; set; }
}

public class ApplicationUserRole : IdentityUserRole<long> { }
public class ApplicationUserClaim : IdentityUserClaim<long> { }

public class ApplicationUserLogin : IdentityUserLogin<long> { }

添加用户并将其添加到角色似乎工作正常。我的问题是当我想从角色中删除用户时。

当我想将用户添加到角色列表中时,我开始使用方法ClearAllUserRoles(long userId)清除用户所在的所有角色,然后将其添加到每个所选角色。像这样:

public ActionResult UserRoles_Update(long RolesSelectedUserId, List<long> SelectedUserRoles)
    {
        if (RolesSelectedUserId == 0)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }
        userInfoRepository = new GenericRepository<UserInfo>(DB);
        UserInfo uInfo = userInfoRepository.GetByID(RolesSelectedUserId);
        UserManager.ClearAllUserRoles(uInfo.UserLoginInfo.Id);
        foreach (var roleId in SelectedUserRoles)
        {
            var roleName = DB.Roles.FirstOrDefault(m => m.Id == roleId).Name;
            if (!UserManager.AddUserToRole(uInfo.UserLoginInfo.Id, roleName))
            {
                return Json(false);
            }
        }
        return Json(true);
    }

我的问题是RemoveFromRole(userId, role)中使用的ClearAllUserRoles(long userId)方法只将ApplicationUser_Id表的字段ApplicationRole_IdAspNetUserRoles置为空,只留下字段当我尝试将用户重新分配给他已经处于以下异常中的角色时,UserIdRoleId已填充:

{"Violation of PRIMARY KEY constraint 'PK_dbo.AspNetUserRoles'. Cannot insert duplicate key in object 'dbo.AspNetUserRoles'. The duplicate key value is (16, 1).\r\nThe statement has been terminated."}

我的问题是:

  1. 我的AspNetUserRoles表格应该包含这4列(ApplicationUser_IdApplicationRole_IdUserIdRoleId)还是我做错了我的数据库上下文的OnModelCreating()方法?

  2. RemoveFromRole(userId, role)方法是否按预期工作,或者应该删除AspNetUserRoles表的所有行?

  3. 更新

    这是我的OnModelCreating()方法:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            if (modelBuilder == null)
            {
                throw new ArgumentNullException("modelBuilder");
            }
    
            EntityTypeConfiguration<ApplicationUser> table =
                modelBuilder.Entity<ApplicationUser>().ToTable("AspNetUsers");
    
            table.Property((ApplicationUser u) => u.UserName).IsRequired();
    
            modelBuilder.Entity<ApplicationUser>().HasMany<ApplicationUserRole>((ApplicationUser u) => u.Roles);
            modelBuilder.Entity<ApplicationUserRole>().HasKey((ApplicationUserRole r) =>
                new { UserId = r.UserId, RoleId = r.RoleId }).ToTable("AspNetUserRoles");
    
            EntityTypeConfiguration<ApplicationUserLogin> entityTypeConfiguration =
                modelBuilder.Entity<ApplicationUserLogin>().HasKey((ApplicationUserLogin l) =>
                    new
                    {
                        UserId = l.UserId,
                        LoginProvider = l.LoginProvider,
                        ProviderKey
                            = l.ProviderKey
                    }).ToTable("AspNetUserLogins");
    
            EntityTypeConfiguration<IdentityUserClaim> table1 =
                modelBuilder.Entity<IdentityUserClaim>().ToTable("AspNetUserClaims");
    
            EntityTypeConfiguration<ApplicationRole> entityTypeConfiguration1 =
                modelBuilder.Entity<ApplicationRole>().ToTable("AspNetRoles");
    
            entityTypeConfiguration1.Property((ApplicationRole r) => r.Name).IsRequired();
    
            modelBuilder.Entity<ApplicationUser>()
                    .HasRequired(p => p.UserInfo).WithOptional(p => p.UserLoginInfo);
        }
    

    在我的迁移中,create table是这样的:

    CreateTable(
                "dbo.AspNetUserRoles",
                c => new
                    {
                        UserId = c.Long(nullable: false),
                        RoleId = c.Long(nullable: false),
                        ApplicationUser_Id = c.Long(),
                        ApplicationRole_Id = c.Long(),
                    })
                .PrimaryKey(t => new { t.UserId, t.RoleId })
                .ForeignKey("dbo.AspNetUsers", t => t.ApplicationUser_Id)
                .ForeignKey("dbo.AspNetRoles", t => t.ApplicationRole_Id)
                .Index(t => t.ApplicationUser_Id)
                .Index(t => t.ApplicationRole_Id);
    

1 个答案:

答案 0 :(得分:2)

您需要覆盖OnModelBuilding

中外键的默认命名

替换

modelBuilder.Entity<ApplicationUser>().HasMany<ApplicationUserRole>((ApplicationUser u) => u.Roles);

modelBuilder.Entity<ApplicationUser>().HasMany(p => p.Roles).WithRequired().HasForeignKey(p => p.UserId);
modelBuilder.Entity<ApplicationRole>().HasMany(p => p.Users).WithRequired().HasForeignKey(p => p.RoleId);

但是,我建议您在方法开始时调用base.OnModelCreating(modelBuilder);,并让股票IdentityDbContext为您完成大部分操作。