Search code examples
c#asp.net-identity-2

can't convert Class to Interface with Generics


I’m trying to extend AspNet Identity by grouping Claims. I’m doing this with a new QueryAppGroup entity. I want to be able to add & remove claims from any particular group. Adding was fine but I can find no way of removing a specific claim (eg, by Id) so here is my plan:

  • Create an intermediary entity called QueryAppGroupClaim so that the IdentityUserClaim has a one-to-zero-or-one relationship with it.

  • By deleting any particular QueryAppGroupClaim entity, the delete should cascade to IdentityUserClaim.

  • To do this, I need to extend IdentityUserClaim with a navigation property back to the QueryAppGroupClaim (see ApplicationUserClaim)

Code:

public class ApplicationUserClaim : IdentityUserClaim<string>
{
    [ForeignKey("QueryAppGroupClaim")]
    public virtual int QueryAppGroupClaimId { get; set; }
    public virtual QueryAppGroupClaim QueryAppGroupClaim { get; set; }
}

public class QueryAppGroup
{
    public QueryAppGroup()
    {
    }

    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }

    [ForeignKey("ApplicationUser")]
    public String UserId { get; set; }

    public String Desc { get; set; }

    public String ImpersonateClaimType { get; set; }

    public virtual ApplicationUser ApplicationUser { get; set; }
}

public class QueryAppGroupClaim
{
    public QueryAppGroupClaim()
    { }

    [Key, ForeignKey("IdentityUserClaim")]
    public int ClaimId { get; set; }
    public virtual ApplicationUserClaim IdentityUserClaim { get; set; }

    [ForeignKey("QueryAppGroup")]
    public int QueryAppGroupId { get; set; }
    public virtual QueryAppGroup QueryAppGroup { get; set; }
}


public class ApplicationUser : IdentityUser<string, IdentityUserLogin, IdentityUserRole, ApplicationUserClaim>, IUser, IUser<string>
{
    //...
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, ApplicationUserClaim>
{
    //...
    public DbSet<QueryAppGroup> QueryAppGroups { get; set; }

    public DbSet<QueryAppGroupClaim> QueryAppGroupClaims { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<ApplicationUserClaim>()
            .HasOptional(t => t.QueryAppGroupClaim)
            .WithRequired(t => t.IdentityUserClaim)
            .WillCascadeOnDelete();
    }
}

public class ApplicationUserStore : UserStore<ApplicationUser,IdentityRole,string, IdentityUserLogin, IdentityUserRole, ApplicationUserClaim>
{
    //...
    //Already exists with an override of RemoveClaimAsync(...)
}

public class ApplicationUserManager : UserManager<ApplicationUser>
{
    public ApplicationUserManager(IUserStore<ApplicationUser> store)
        : base(store)
    {
    }

    public ApplicationUserManager(ApplicationUserStore store)
        : base(store)
    {

    }
    //...
}

I’m getting a compiliation error with public ApplicationUserManager(ApplicationUserStore store) : base(store) when calling the base constructor saying Argument 1: cannot convert from 'ApplicationUserStore' to 'Microsoft.AspNet.Identity.IUserStore<ApplicationUser>'. My class ApplicationUserStore extends UserStore, which itself implements a number of interfaces, one being IUserStore. I can’t see how to resolve this. Please help.

Any suggestions on making the main objective easier would also be welcome!


Solution

  • Try explicitly implementing IUserStore<ApplicationUser> along with the base class declaration for UserStore, like this:

    public class ApplicationUserStore :
        UserStore<ApplicationUser, IdentityRole, string, IdentityUserLogin, IdentityUserRole, ApplicationUserClaim>,
        IUserStore<ApplicationUser>
    {
        public ApplicationUserStore(DbContext context) : base(context)
        {
    
        }
    }