Why am I getting an IdentityRole error?

后端 未结 1 573
误落风尘
误落风尘 2021-01-03 06:59

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 i

相关标签:
1条回答
  • 2021-01-03 07:12

    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!

    0 讨论(0)
提交回复
热议问题