Why am I getting an IdentityRole error?

时光毁灭记忆、已成空白 提交于 2019-11-30 16:03:31
Sean Newcome

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!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!