扩展ASP.NET标识角色:IdentityRole不是当前上下文模型的一部分
我正在尝试在我的MVC5应用程序中使用新的ASP.NET标识,特别是我正在尝试将ASP.NET标识集成到现有数据库中。 我已经阅读了有关DB First和ASP.NET Identity的问题/答案,并且遵循了所有建议我仍然无法将角色添加到我的数据库中,尽管添加用户没有任何问题。 这是我的代码:
var context = new PayrollDBEntities(); var roleManager = new RoleManager(new RoleStore(context)); bool roleExists = roleManager.RoleExists(roleDto.Name); if (roleExists){ return false; } var role = new AspNetRole(roleDto.Name){ Name = roleDto.Name, }; IdentityResult result = roleManager.Create(role);//Getting exception here
在代码的最后一行,我得到类型'System.InvalidOperationException': The entity type IdentityRole is not part of the model for the current context.
的exception'System.InvalidOperationException': The entity type IdentityRole is not part of the model for the current context.
这是我的背景:
public partial class PayrollDBEntities : IdentityDbContext { public PayrollDBEntities() : base("name=PayrollDBEntities") { } public virtual DbSet AspNetRoles { get; set; } public virtual DbSet AspNetUserClaims { get; set; } public virtual DbSet AspNetUserLogins { get; set; } public virtual DbSet AspNetUsers { get; set; } ...... }
我的AspNetUser
和AspNetRole
类分别来自IdentityUser
和IdentityRole
,但我仍然得到了这个例外。 这是我的数据库图:
任何帮助将不胜感激。
您必须在创建用户存储期间指定使用AspNetRole而不是IdentityRole。 您可以通过使用带有6个类型参数的UserStore类来实现此目的:
new UserStore(new PayrollDBEntities());
这表示用户管理器创建时也会发生更改。 以下是有关创建所需实例的简化示例:
public class AspNetUser : IdentityUser { /*customization*/ } public class AspNetRole : IdentityRole { /*customization*/ } public class PayrollDBEntities : IdentityDbContext //or : IdentityDbContext { } public class Factory { public IdentityDbContext DbContext { get { return new PayrollDBEntities(); } } public UserStore UserStore { get { return new UserStore(DbContext); } } public UserManager UserManager { get { return new UserManager(UserStore); } } public RoleStore RoleStore { get { return new RoleStore (DbContext); } } public RoleManager RoleManager { get { return new RoleManager (RoleStore); } } }
在尝试以干净的方式工作几天之后,我得出的结论是,如果您首先使用数据库并希望将ASP.NET身份集成到您的应用程序中,那么这是迄今为止最简单,最干净的解决方案是通过重写ASP.NET标识来创建自己的成员资格提供程序。 它实际上非常简单,到目前为止,我已经按照自己的喜好实现了UserStore
和RoleStore
。 我在我的数据库中添加了特定于我的域的列/关系,每当我创建用户或角色时,我通过添加所需的关系来处理我的数据库提交。 我的UserStore
实现与此非常相似。 我的RoleStore
实现是这样的:
public class ApplicationRoleStore : IRoleStore { private PayrollDBEntities _context; public ApplicationRoleStore() { } public ApplicationRoleStore(PayrollDBEntities database) { _context = database; } public Task CreateAsync(ApplicationRoleDTO role) { if (role == null) { throw new ArgumentNullException("RoleIsRequired"); } var roleEntity = ConvertApplicationRoleDTOToAspNetRole(role); _context.AspNetRoles.Add(roleEntity); return _context.SaveChangesAsync(); } public Task DeleteAsync(ApplicationRoleDTO role) { var roleEntity = _context.AspNetRoles.FirstOrDefault(x => x.Id == role.Id); if (roleEntity == null) throw new InvalidOperationException("No such role exists!"); _context.AspNetRoles.Remove(roleEntity); return _context.SaveChangesAsync(); } public Task FindByIdAsync(string roleId) { var role = _context.AspNetRoles.FirstOrDefault(x => x.Id == roleId); var result = role == null ? null : ConvertAspNetRoleToApplicationRoleDTO(role); return Task.FromResult(result); } public Task FindByNameAsync(string roleName) { var role = _context.AspNetRoles.FirstOrDefault(x => x.Name == roleName); var result = role == null ? null : ConvertAspNetRoleToApplicationRoleDTO(role); return Task.FromResult(result); } public Task UpdateAsync(ApplicationRoleDTO role) { return _context.SaveChangesAsync(); } public void Dispose() { _context.Dispose(); } private ApplicationRoleDTO ConvertAspNetRoleToApplicationRoleDTO(AspNetRole aspRole) { return new ApplicationRoleDTO{ Id = aspRole.Id, EnterpriseId = aspRole.EnterpriseId, Name = aspRole.Name }; } private AspNetRole ConvertApplicationRoleDTOToAspNetRole(ApplicationRoleDTO appRole) { return new AspNetRole{ Id = appRole.Id, EnterpriseId = appRole.EnterpriseId, Name = appRole.Name, }; } }
和我的ApplicationRoleDTO:
public class ApplicationRoleDTO : IRole { public ApplicationRoleDTO() { Id = Guid.NewGuid().ToString(); } public ApplicationRoleDTO(string roleName) : this() { Name = roleName; } public string Id { get; set; } public string Name { get; set; } public Guid EnterpriseId { get; set; } }
我还发现这两篇文章非常有帮助:
ASP.NET身份的自定义存储提供程序概述
实现自定义MySQL ASP.NET身份存储提供程序
我将在这里解释代码示例:)。
诀窍是,它们已经在IdentityDbContext中(AspNetRoles,AspNetUserClaims,AspNetUsers,….)
在IdentityModel中,您将看到ApplicationUser在顶部为空。 如果要自定义这些用户或角色,只需在此处添加属性,然后通过控制台更新数据库
我的上下文的例子
public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext() : base("DefaultConnection") { } public DbSet Requests { get; set; } public DbSet Reservations { get; set; } public DbSet PriceTypes { get; set; } public DbSet Products { get; set; } public DbSet Prices { get; set; } public DbSet Posts { get; set; } public DbSet Counts { get; set; } public DbSet Invoices { get; set; } public DbSet InvoiceLines { get; set; } ... }
所以这里没有定义应用程序用户,但我确实为它添加了更多属性,例如:
public class ApplicationUser : IdentityUser { public string FirstName { get; set; } public string LastName { get; set; } public string GroupName { get; set; } public string Email { get; set; } [StringLength(15)] public string Phone { get; set; } public string Remark { get; set; } public DateTime? BirthDate { get; set; } public DateTime ValidFrom { get; set; } public DateTime ValidUntil { get; set; } public string Street { get; set; } public string ZipCode { get; set; } public string City { get; set; } public virtual ICollection Requests { get; set; } }
我知道这是一个老问题,但是万一其他人在修改asp身份以使用数字主键(int / long)而不是Identity Roles的默认字符串时,很难添加角色/用户,所以如果您已将IdentityModels.cs中的IdentityUserRole更改为以下内容:
public class Role : IdentityRole { public Role() { } public Role(string name) { Name = name; } }
在构造RoleManager时,您必须使用类Role
而不是默认的IdentityRole
,因此您的代码应如下所示:
public static void RegisterUserRoles() { ApplicationDbContext context = new ApplicationDbContext(); var RoleManager = new RoleManager(new RoleStore(context)); if (!RoleManager.RoleExists("Administrador")) { var adminRole = new Role { Name = "Administrador", }; RoleManager.Create(adminRole); } }
因此,这应该正确填充您的数据库,我认为所有经验丰富的ASP程序员已经知道这一点,但对于其他人来说,这可能需要一些时间来弄清楚。
我通过更改web.config DefaultConnection connectionString属性来解决此问题,因此它指向新的SQLServer数据库
- 将用户名和姓氏添加到ASP.NET标识2?
- 将asp.net MVC从5.0.0-beta2更新为5.0.0-rc1
- 更改ASP.NET标识存储用户数据的数据库
- 从基础asp.net标识用户创建inheritance用户
- 扩展ASP.NET身份
- 刷新ASP.Net核心标识中的用户cookie票证
- 你能扩展HttpContext.Current.User.Identity属性吗?
- 如何设置asp.net标识cookie到期时间
- 为什么在使用带有ASP.Net Identity的ApplicationCookie之前调用SignOut(DefaultAuthenticationTypes.ExternalCookie)?