Using Identity 2.0 After registering a user, the user is created in the database, there is code in the Account controller to create an identity and sign the user in. This is when I get the error. Here is the code producing the error:
var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
And here is the error:
The entity type IdentityRole is not part of the model for the current
context.
My Model looks like this:
namespace MyApp.Models
{
public class ApplicationUser : IdentityUser
{
[Required]
[StringLength(50)]
public string FirstName { get; set; }
[Required]
[StringLength(50)]
public string LastName { get; set; }
}
public class ApplicationRole : IdentityRole
{
[Required]
[StringLength(50)]
public string ProperName { get; set; }
[Required]
public string Description { get; set; }
}
public class MyAppDb : IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
{
public MyAppDb()
: base("MyAppDb")
{
}
}
}
My UserManager
is created like this in the Account controller:
namespace MyApp.Controllers
{
[Authorize]
public class AccountController : BaseController
{
private UserManager<ApplicationUser> _userManager;
public AccountController()
{
}
public AccountController(UserManager<ApplicationUser> userManager)
{
UserManager = userManager;
}
public UserManager<ApplicationUser> UserManager
{
get
{
return _userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new MyAppDb()));
}
private set
{
_userManager = value;
}
}
...
}
}
I've spent a lot of time on this issue and posted many questions to get to the bottom of it. I sure hope this information helps other folks.
Basically, customizing the User
is easy and there are several examples available. However, customizing the Role
is problematic and the only examples I found were customized far beyond what comes "out of the box" and I was able to get one working after resolving an Id
issue. The issue in that case was that I had to create the Id
myself. Here is that issue: UserManager.Create(user, password) thowing EntityValidationError saying Id is required?
So in simple examples, notice when you are just customizing the User
your DbContext
inherits from IdentityDbContext
and you just provide the IdentityUser
, in my case it was called ApplicationUser
and looked like this IdentityDbContext<ApplicationUser>
. Also notice that the UserManager
and UserStore
is provided the IdentityUser
as well, and in most examples looks like this new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()))
But once you customize your Role
you need to pass everything, including the key type TKey
of the Id
fields. Mine looks like this IdentityDbContext<ApplicationUser, ApplicationRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
because I only customized the User
and Role
.
But you aren't done yet, because the regular UserManager
doesn't understand anymore. I think this is something the Identity folks could/should fix, but I digress. So I had to implement my own UserStore
and UserManager
and notice (and this is the part that tripped me up) you have to provide the KType
here too or instantiating your custom UserManager
will give you a compile-time error:
public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
{
public ApplicationUserStore(MyAppDb context)
: base(context)
{
}
}
public class ApplicationUserManager : UserManager<ApplicationUser, string>
{
public ApplicationUserManager(IUserStore<ApplicationUser, string> store)
: base(store)
{
}
}
And instantiate the UserManager
in the Account controller like this new ApplicationUserManager(new ApplicationUserStore(new MyAppDb()))
:
public class AccountController : BaseController
{
private ApplicationUserManager _userManager;
public AccountController()
{
}
public AccountController(ApplicationUserManager userManager)
{
UserManager = userManager;
}
public ApplicationUserManager UserManager
{
get
{
return _userManager = new ApplicationUserManager(new ApplicationUserStore(new MyAppDb()));
}
private set
{
_userManager = value;
}
}
...
}
Hope this helps!