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:
- Create an ASP.NET Web Application
- Make sure you select MVC and the Authentication is Individual User Accounts
-
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 } -
Change
GenerateUserIdentityAsyncmethod ofApplicationUserto accept parameter of type ofUserManager<ApplicationUser, string>:public class ApplicationUser : IdentityUser { public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, string> manager) { -
Change
ApplicationDbContextbase class and introduce all the generic parameters:public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim> { public ApplicationDbContext() : base("DefaultConnection") { - Build the project.
- Go to TOOLS menu → Nuget Package Manager → click Package Manager Console
- Type
Enable-Migrationsand press Enter and wait until the task get completed. - Type
Add-Migration "ApplicationRole"and press Enter and wait until the task get completed. - Type
Update-Databaseand press Enter and wait until the task get completed. -
Go to App_Start folder → Open IdentityConfig.cs and Change the
ApplicationUserManagerclass to derive fromUserManager<ApplicationUser, string>and also change itsCreatemethod to return aUserManageaware ofApplicationRole: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>())); -
To manage roles, create
ApplicationRoleManagerclass 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>())); } } -
Go to App_Start folder → Open Startup.Auth.cs and add the following code to the
ConfigureAuthmethod: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