Search code examples
asp.netentity-frameworkasp.net-identityclaims-based-identityusermanager

Microsoft Identity Custom User, Role, Claim Inheritance


Hi guys i'am trying to inherit from the standard AspNet tables.

My intention was to use Guid as Primary key and extendig the basic AspNetUser with some Properties. Furthermore I wanted to rename the table names.

Right now it is like:

public class User : IdentityUser<Guid, UserLogin, UserRole, UserClaim>
{

    public User() { }

    public User(string userName)
    {
        this.UserName = userName;
    }


    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<User, Guid> 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;
    }
 }

My DbContext looks like this:

 public class CustomDBContext : IdentityDbContext<User, Role, Guid, UserLogin, UserRole, UserClaim>
{

     public static CustomDBContext Create()
    {
        return new CustomDBContext();
    }

     protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {

        base.OnModelCreating(modelBuilder);

        modelBuilder.Entity<IdentityRole<Guid, UserRole>>().ToTable("Roles");
        modelBuilder.Entity<IdentityUserLogin<Guid>>().ToTable("UserLogins");
        modelBuilder.Entity<IdentityUserClaim<Guid>>().ToTable("UserClaims");
        modelBuilder.Entity<IdentityUserRole<Guid>>().ToTable("UserRoles");
        modelBuilder.Entity<IdentityUser<Guid, UserLogin, UserRole, UserClaim>>().ToTable("Users");

    }
}

Unfortunately when Iam trying to generate my Migration. I get that error:

The type 'Microsoft.AspNet.Identity.EntityFramework.IdentityRole`2[System.Guid,Easy1WebAPIData.Models.UserRole]' was not mapped. Check that the type has not been explicitly excluded by using the Ignore method or NotMappedAttribute data annotation. Verify that the type was defined as a class, is not primitive or generic, and does not inherit from EntityObject.

Any ideas ? Best regards!


Solution

  • I believe that you just need to map your extended models in the OnModelCreating method. I am doing the following on a project of mine and it is working well with migrations.

    public class ApplicationUser : IdentityUser<Guid, CustomUserLogin, CustomUserRole, CustomUserClaim> { }
    public class CustomUserRole : IdentityUserRole<Guid> { }
    public class CustomUserClaim : IdentityUserClaim<Guid> { }
    public class CustomUserLogin : IdentityUserLogin<Guid> { }
    public class CustomRole : IdentityRole<Guid, CustomUserRole> { }
    
    public class ApplicationDbContext : IdentityDbContext<ApplicationUser, CustomRole, Guid, CustomUserLogin, CustomUserRole, CustomUserClaim> 
    {
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<ApplicationUser>().ToTable("Users");
            modelBuilder.Entity<CustomRole>().ToTable("Roles");
            modelBuilder.Entity<CustomUserRole>().ToTable("UserRoles");
            modelBuilder.Entity<CustomUserLogin>().ToTable("UserLogins");
            modelBuilder.Entity<CustomUserClaim>().ToTable("UserClaims");
        }
    }
    

    Also, if you're using Guid's for keys, it is very common for you to set the Id in the constructor of the objects.

    public class ApplicationUser : IdentityUser<Guid, CustomUserLogin, CustomUserRole, CustomUserClaim>
    {
        public ApplicationUser()
        {
            public ApplicationUser()
            {
                Id = Guid.NewGuid();
            }
        }
    }