为啥 UserManager.CreateIdentityAsync() 正在寻找 IdentityRole 以及如何解决?

Posted

技术标签:

【中文标题】为啥 UserManager.CreateIdentityAsync() 正在寻找 IdentityRole 以及如何解决?【英文标题】:Why is UserManager.CreateIdentityAsync() looking for IdentityRole and how to fix?为什么 UserManager.CreateIdentityAsync() 正在寻找 IdentityRole 以及如何解决? 【发布时间】:2014-05-05 12:59:40 【问题描述】:

我使用 Identity2.0MVC5 CodeFirst 我已经扩展了 IdentityUserIdentityRole,如下所示:

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")
    
    

注意MyAppDb 继承自IdentityDbContext,但我传递的是ApplicationRole 而不是IdentityRole。我的ApplicationRole 继承自IdentityRole,所以这应该不是问题。

但是……

我的AccountController 抛出这个错误:

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

在此代码中的UserManager.CreateIdentityAsync(...)

private async Task SignInAsync(ApplicationUser user, bool isPersistent)

     AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
     var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);
     AuthenticationManager.SignIn(new AuthenticationProperties()  IsPersistent = isPersistent , identity);

user 正在这里创建:

        var user = await UserManager.FindAsync(model.UserName, model.Password);
        if (user != null)
        
            await SignInAsync(user, model.RememberMe);
            return RedirectToLocal(returnUrl);
        

什么是“重大故障”? ;)

更新: 我很确定这个问题与这里的UserStore 有关:

    public class AccountController : Controller
    
        public AccountController ()
            : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new MyAppDb())))
        
        

        public AccountController (UserManager<ApplicationUser> userManager)
        
            UserManager = userManager;
            UserManager.PasswordValidator = (IIdentityValidator<string>)new MinimumLengthValidator(8);
            UserManager.UserValidator = new UserValidator<ApplicationUser>(UserManager)  AllowOnlyAlphanumericUserNames = false ;
        

        public UserManager<ApplicationUser> UserManager  get; private set; 
...

当我只能传递一个参数时,如何让 UserStore 了解 ApplicationRole

【问题讨论】:

请注意这个项目从 AspNetIdentity1.* 开始,然后升级到 AspNetIdentity2.0,这可能会有所帮助。升级后,我扩展了 IdentityRole,更改了 MyAppDb 的签名,正如您在我的问题中看到的那样,问题就开始了。 您的user 是否有与之关联的Roles。如果是,请说明user 是如何创建的。 是的。我这样创建了用户: var result = await UserManager.CreateAsync(user, model.Password);其中“用户”是 ApplicationUser。我直接在数据库中将用户添加到角色中,从用户表中复制用户 ID,从角色表中复制角色 ID。非常直接。 我提到了ApplicationUser user 传递给SignInAsync方法的ApplicationUser user参数,它是如何创建的? 【参考方案1】:

我通过创建ApplicationUserStoreApplicationUserManager 解决了这个问题:

public class ApplicationUser : IdentityUser<string, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>

    [Required]
    [StringLength(50)]
    public string FirstName  get; set; 

    [Required]
    [StringLength(50)]
    public string LastName  get; set; 

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(ApplicationUserManager manager)
    
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    



public class ApplicationUserLogin : IdentityUserLogin<string>



public class ApplicationUserClaim : IdentityUserClaim<string>



public class ApplicationUserRole : IdentityUserRole<string>



public class ApplicationRole : IdentityRole<string, ApplicationUserRole>

    [Required]
    [StringLength(50)]
    public string ProperName  get; set; 



public class MyAppDb : IdentityDbContext<ApplicationUser, ApplicationRole, string, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>

    public static MyAppDb Create()
    
        return new MyAppDb();
    

    public MyAppDb()
        : base("MyAppDb")
    
    



public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, string, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>

    public ApplicationUserStore(MyAppDb context)
        : base(context)
    
    


public class ApplicationUserManager : UserManager<ApplicationUser, string>

    public ApplicationUserManager(IUserStore<ApplicationUser, string> store)
        : base(store)
    
    

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options)
    
        var manager = new ApplicationUserManager(new ApplicationUserStore(new MyAppDb()));
        // Configure the application user manager
        manager.UserValidator = new UserValidator<ApplicationUser>(manager)
        
            AllowOnlyAlphanumericUserNames = false,
            RequireUniqueEmail = true
        ;
        manager.PasswordValidator = (IIdentityValidator<string>)new MinimumLengthValidator(8);

        return manager;
    


public class ApplicationRoleStore : RoleStore<ApplicationRole, string, ApplicationUserRole>

    public ApplicationRoleStore(MyAppDb context)
        : base(context)
    
    


public class ApplicationRoleManager : RoleManager<ApplicationRole, string>

    public ApplicationRoleManager(IRoleStore<ApplicationRole, string> store)
        : base(store)
    
    

    public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options)
    
        var manager = new ApplicationRoleManager(new ApplicationRoleStore(new MyAppDb()));

        return manager;
    

【讨论】:

也对我有用,但您可以使用ApplicationUserStore : UserStore&lt;ApplicationUser, ApplicationRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim&gt; 保存最后三个推导。

以上是关于为啥 UserManager.CreateIdentityAsync() 正在寻找 IdentityRole 以及如何解决?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?

为啥需要softmax函数?为啥不简单归一化?

为啥 g++ 需要 libstdc++.a?为啥不是默认值?

为啥或为啥不在 C++ 中使用 memset? [关闭]

为啥临时变量需要更改数组元素以及为啥需要在最后取消设置?

为啥 CAP 定理中的 RDBMS 分区不能容忍,为啥它可用?