AspNetCore.Identity无法使用自定义用户/角色实现
因为我倾向于支持Guid
作为我的主键类型,所以我的User
和Role
类实现如下
public class User : IdentityUser { } public class Role : IdentityRole { }
请注意, UserClaim
, UserRole
, UserLogin
和RoleClaim
都以相同的方式实现
这是我的DbContext
实现
public class ApplicationDbContext : IdentityDbContext { }
到目前为止一切都很好,除了AspNetCore的新DI容器似乎不喜欢我的默认自定义实现。 我的Startup.cs文件中的以下代码行引发了下面显示的错误
services .AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders();
GenericArguments [0],’NewCo.DomainModel.Models.Identity.User’,’Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`4 [TUser,TRole,TContext,TKey]’违反了类型’TUser’的约束。
我假设这是因为默认的Identity gremlin被实现为使用IdentityUser
,我正在使用IdentityUser
。
接下来我该怎么办? (我完全没有想法)
注意:我正在构建截至周一(2016年6月27日)和Visual Studio Update 3(如果对任何人有任何帮助)的Microsoft官方.NET Core和ASP.NET Core版本
由于您使用的是自定义密钥类型,因此必须在调用AddEntityFrameworkStores
时指定它:
services .AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders();
我最终得到了这个解决方案:
实际上我创建了自己的抽象IdentityDbContext
然后你可以传递任何自定义模型,唯一的问题是在创建数据库时,EF会向用户和角色以外的所有表添加一个Disriminator字段(inheritance)
public abstract class ApplicationDbContext : IdentityDbContext where TUser : IdentityUser where TRole : IdentityRole where TKey : IEquatable where TUserClaim : IdentityUserClaim where TUserRole : IdentityUserRole where TUserLogin : IdentityUserLogin where TRoleClaim : IdentityRoleClaim where TUserToken : IdentityUserToken { public ApplicationDbContext(DbContextOptions options) : base(options) { } protected ApplicationDbContext() { } public new DbSet RoleClaims { get; set; } public new DbSet Roles { get; set; } public new DbSet UserClaims { get; set; } public new DbSet UserLogins { get; set; } public new DbSet UserRoles { get; set; } public new DbSet Users { get; set; } public new DbSet UserTokens { get; set; } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); } } public class AppDbContext : ApplicationDbContext { public AppDbContext(DbContextOptions options) : base(options) { } //public new DbSet UserClaims { get; set; } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); // Customize the ASP.NET Identity model and override the defaults if needed. // For example, you can rename the ASP.NET Identity table names and more. // Add your customizations after calling base.OnModelCreating(builder); } } services.AddIdentity() .AddEntityFrameworkStores() .AddDefaultTokenProviders() .AddUserStore>() .AddRoleStore>() public class ApplicationUser : IdentityUser { public ApplicationUser() { //this.Id = Guid.NewGuid(); } public ApplicationUser(string userName) : this() { this.UserName = userName; } public Guid ClientId { get; set; } //public new ICollection Claims { get; set; } } //public class ApplicationRole : IdentityRole public class ApplicationRole : IdentityRole { public ApplicationRole() { //this.Id = Guid.NewGuid(); } public ApplicationRole(string name) : this() { this.Name = name; } } public class ApplicationRoleClaim : IdentityRoleClaim { } //[NotMapped] public class ApplicationUserClaim : IdentityUserClaim { } public class ApplicationUserLogin : IdentityUserLogin { } public class ApplicationUserRole : IdentityUserRole { } public class ApplicationUserToken : IdentityUserToken { }
“UserStore`4 [TUser,TRole,TContext,TKey]’违反了’TUser’类型的约束。”
您需要使用Guid创建UserStore,以及更改DbContext
public class ApplicationUser : IdentityUser { } public class ApplicationRole : IdentityRole { } public class ApplicationUserStore : UserStore { public ApplicationUserStore(ApplicationDbContext context, IdentityErrorDescriber describer = null) : base(context, describer) { } }
新的ApplicationDbContextinheritance
public class ApplicationDbContext : IdentityDbContext { public ApplicationDbContext(DbContextOptions options) : base(options) { } protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); } }
在您的startup.cs中
services .AddIdentity() .AddUserStore() .AddEntityFrameworkStores() .AddDefaultTokenProviders();
在使用自定义用户和角色实体的情况下指定.AddEntityFrameworkStore()方法的键。在启动时注册身份
.AddEntityFrameworkStores()