The entity type IdentityRole is not part of the model for the current context after extending Roles table

I have extended my AspNetRoles that was created by Entity Framework to look like this:

public class AspNetRoles:IdentityRole
{
        public AspNetRoles() : base() { }
        public String Label { get; set; }
        public String ApplicationId { get; set; }
        public AspNetApplications Application { get; set; }

        public static readonly String SystemAdministrator = "SystemAdministrator";
}

I understood that because I have extended the identityrole table, I had to make changes to my usermanager. This is what I have done:

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

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    {
        var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>()));
        // Configure validation logic for usernames
        manager.UserValidator = new UserValidator<ApplicationUser>(manager)
        {
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        };

        // Configure validation logic for passwords
        manager.PasswordValidator = new PasswordValidator
        {
            RequiredLength = 6,
            RequireNonLetterOrDigit = true,
            RequireDigit = true,
            RequireLowercase = true,
            RequireUppercase = true,
        };

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

        // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
        // You can write your own provider and plug it in here.
        manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser>
        {
            MessageFormat = "Your security code is {0}"
        });
        manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser>
        {
            Subject = "Security Code",
            BodyFormat = "Your security code is {0}"
        });
        manager.EmailService = new EmailService();
        manager.SmsService = new SmsService();
        var dataProtectionProvider = options.DataProtectionProvider;
        if (dataProtectionProvider != null)
        {
            manager.UserTokenProvider = 
                new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity"));
        }
        return manager;
    }
}

// Configure the application sign-in manager which is used in this application.
public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
{
    public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager)
        : base(userManager, authenticationManager)
    {
    }

    public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
    {
        return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
    }

    public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
    {
        return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
    }
}

public class ApplicationRoleManager : RoleManager<AspNetRoles>, IDisposable
{
    public ApplicationRoleManager(RoleStore<AspNetRoles> store) : base(store)
    { }


    public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context)
    {
        //AppIdentityDbContext db = context.Get<AppIdentityDbContext>();
        //AppRoleManager manager = new AppRoleManager(new RoleStore<AppRole>(db));
        return new ApplicationRoleManager(new RoleStore<AspNetRoles>(context.Get<ApplicationDbContext>()));

        //return manager;
    }
}

public class ApplicationUserStore<TUser> : UserStore<TUser, AspNetRoles, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>, IUserStore<TUser>, IUserStore<TUser, string>, IDisposable where TUser : IdentityUser
{
    public ApplicationUserStore(DbContext context) : base(context) { }
}

This is my DBContext:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, AspNetRoles, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
    {
        public virtual DbSet<AspNetUsersExtendedDetails> AspNetUsersExtendedDetails { get; set; }
        public virtual DbSet<AspNetApplications> AspNetApplications { get; set; }
        public virtual DbSet<AspNetEventLogs> AspNetEventLogs { get; set; }
        public ApplicationDbContext() : base("AppStudio")
        {

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

However, I get this error when I start my application:

The entity type IdentityRole is not part of the model for the current context.

I’m not sure why this is happening. Have I missed something that needs to be changed after extending my roles table?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Short answer

The main problem in above code is in Create method of UserManager. In that method, you should create a UserManager using a UserStore which is aware of the new role class which you created. To do so, you can use an instance of ApplicationUserStore class which you have or create a new user store this way:

new UserStore<ApplicationUser, [YourRoleClass], string, 
    IdentityUserLogin, IdentityUserRole, IdentityUserClaim(
        context.Get<ApplicationDbContext>())

How to Add a custom Property to IdentityRole?

To add a new property to IdentityRole, you can follow the following steps:

  1. Create an ASP.NET Web Application
  2. Make sure you select MVC and the Authentication is Individual User Accounts
  3. Go to Models folder → Open IdentityModels.cs and Create ApplicationRole class containing the custom property that you want to add:
    public class ApplicationRole : IdentityRole   //My custom role class
    {
        public string ApplicationId { get; set; } //My custom property
    }
  4. Change GenerateUserIdentityAsync method of ApplicationUser to accept parameter of type of UserManager<ApplicationUser, string>:
    public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, string> manager)
        {
  5. Change ApplicationDbContext base class and introduce all the generic parameters:
    public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
    {
        public ApplicationDbContext()
            : base("DefaultConnection")
        {
  6. Build the project.
  7. Go to TOOLS menu → Nuget Package Manager → click Package Manager Console
  8. Type Enable-Migrations and press Enter and wait until the task get completed.
  9. Type Add-Migration "ApplicationRole" and press Enter and wait until the task get completed.
  10. Type Update-Database and press Enter and wait until the task get completed.
  11. Go to App_Start folder → Open IdentityConfig.cs and Change the ApplicationUserManager class to derive from UserManager<ApplicationUser, string> and also change its Create method to return a UserManage aware of ApplicationRole:
    public class ApplicationUserManager : UserManager<ApplicationUser, string>
    {
        public ApplicationUserManager(IUserStore<ApplicationUser, string> store)
            : base(store)
        {
        }
    
        public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
        {
            var manager = new ApplicationUserManager(new UserStore<ApplicationUser, ApplicationRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>(context.Get<ApplicationDbContext>()));
  12. To manage roles, create ApplicationRoleManager class in the same file:
    public class ApplicationRoleManager : RoleManager<ApplicationRole>
    {
        public ApplicationRoleManager(IRoleStore<ApplicationRole, string> store) : base(store) { }
    
        public static ApplicationRoleManager Create(
            IdentityFactoryOptions<ApplicationRoleManager> options,
            IOwinContext context)
        {
            return new ApplicationRoleManager(new RoleStore<ApplicationRole>(context.Get<ApplicationDbContext>()));
        }
    }
  13. Go to App_Start folder → Open Startup.Auth.cs and add the following code to the ConfigureAuth method:
    ConfigureAuthapp.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);

Now the project is ready to take advantage of the new ApplicationRole.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x