首页 > 解决方案 > 为不同的应用程序添加同名角色

问题描述

我刚刚像这样扩展了我的 IdentityRole:

public class AspApplicationRoles : IdentityRole
{
    public AspApplicationRoles() : base() { }
    public AspApplicationRoles(String Name) : base(Name) { }
    [Required]
    public String ApplicationId { get; set; }
    public AspNetApplications Application { get; set; }
}

然后,为了添加相同的角色名称但具有不同的 ApplicationId,我创建了一个自定义角色验证器,如下所示:

    public class ApplicationRoleValidator<TRole> : RoleValidator<TRole> where TRole : AspApplicationRoles
    {
        private RoleManager<TRole, string> Manager { get; set; }
        private AspApplicationRoles data = new AspApplicationRoles();
        private ApplicationDbContext dbContext = new ApplicationDbContext();

        public ApplicationRoleValidator(RoleManager<TRole, string> manager) : base(manager)
        {
            Manager = manager;
        }

        public override async Task<IdentityResult> ValidateAsync(TRole Input)
        {
            data = dbContext.AspApplicationRoles.Where(ar => ar.ApplicationId == Input.ApplicationId && ar.Name == Input.Name).SingleOrDefault();
            if (data == null)
            {
                return IdentityResult.Success;
            }
            else
            {
                return IdentityResult.Failed("Role already exists");
            }
        }
    }

然后我不得不像这样更改我的 applicationRoleManagers:

public class ApplicationRoleManager : RoleManager<AspApplicationRoles>
{
    public ApplicationRoleManager(IRoleStore<AspApplicationRoles, string> roleStore)
        : base(roleStore)
    {
        RoleValidator = new ApplicationRoleValidator<AspApplicationRoles>(this);
    }
    public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context)
    {
        var manager = new ApplicationRoleManager(new ApplicationRoleStore(context.Get<ApplicationDbContext>()));
        return manager;
    }
}

我还删除了数据库表上的唯一键,如下所示:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        var role = modelBuilder.Entity<IdentityRole>()
            .ToTable("AspNetRoles");
        role.Property(r => r.Name)
            .IsRequired()
            .HasMaxLength(256)
            .HasColumnAnnotation("Index", new IndexAnnotation(
                new IndexAttribute("RoleNameIndex")
                { IsUnique = false }));
    }

但是,我仍然不能拥有相同的角色名称,并且我仍然得到 EntityValidationError "Role Manager already exists。我试图寻找解决方案,但我似乎无法找到或看到它。

编辑:

这就是我如何称呼我的新角色验证器

    public bool Save(SaveRolesDetailsViewModel Input)
    {
        bool result = false;
        AspApplicationRoles data = new AspApplicationRoles();
        var store = new ApplicationRoleStore(new ApplicationDbContext());
        var manager =new ApplicationRoleManager(store);
        try
        {
            var role = new AspApplicationRoles
            {
                Name = Input.RoleName,
                ApplicationId = Input.ApplicationId
            };
            var res = manager.RoleValidator.ValidateAsync(role);
            if (res.Result.Succeeded)
            {
                manager.Create(role);
                result = true;
            }
            else
            {
                result = false;
            }
        }
        catch (Exception e)
        {
            logger.Error(e, AspNetEventLogs.NotFound);
        }
        return result;
    }

编辑2:

添加了添加 OnModelCreating 后生成的迁移文件:

    public override void Up()
    {
        DropIndex("dbo.AspNetRoles", "RoleNameIndex");
        CreateIndex("dbo.AspNetRoles", "Name", name: "RoleNameIndex");
    }

    public override void Down()
    {
        DropIndex("dbo.AspNetRoles", "RoleNameIndex");
        CreateIndex("dbo.AspNetRoles", "Name", unique: true, name: "RoleNameIndex");
    }

标签: c#asp.netasp.net-mvcentity-framework

解决方案


推荐阅读