为啥 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.0 和 MVC5 CodeFirst 我已经扩展了 IdentityUser
和 IdentityRole
,如下所示:
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】:
我通过创建ApplicationUserStore
和ApplicationUserManager
解决了这个问题:
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<ApplicationUser, ApplicationRole, string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
保存最后三个推导。以上是关于为啥 UserManager.CreateIdentityAsync() 正在寻找 IdentityRole 以及如何解决?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 DataGridView 上的 DoubleBuffered 属性默认为 false,为啥它受到保护?