[英]AspNetCore.Identity not working with custom User/Role implementation
Because I tend to favour Guid
as my primary key type, my User
and Role
classes are implemented as follows因为我倾向于使用
Guid
作为我的主键类型,所以我的User
和Role
类实现如下
public class User : IdentityUser<Guid, UserClaim, UserRole, UserLogin>
{
}
public class Role : IdentityRole<Guid, UserRole, RoleClaim>
{
}
Note that UserClaim
, UserRole
, UserLogin
& RoleClaim
are all implemented in the same manner请注意,
UserClaim
、 UserRole
、 UserLogin
和RoleClaim
都以相同的方式实现
Here is my DbContext
implementation这是我的
DbContext
实现
public class ApplicationDbContext : IdentityDbContext<User, Role, Guid, UserClaim, UserRole, UserLogin, RoleClaim, UserToken>
{
}
All good so far, except AspNetCore's new DI container doesn't seem to like my custom implementation by default.到目前为止一切都很好,除了 AspNetCore 的新 DI 容器在默认情况下似乎不喜欢我的自定义实现。 The following line of code, from my Startup.cs file throws the error shown below
来自我的 Startup.cs 文件的以下代码行引发如下所示的错误
services
.AddIdentity<User, Role>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
GenericArguments[0], 'NewCo.DomainModel.Models.Identity.User', on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`4[TUser,TRole,TContext,TKey]' violates the constraint of type 'TUser'.
GenericArguments[0], 'NewCo.DomainModel.Models.Identity.User', on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`4[TUser,TRole,TContext,TKey]' 违反了类型'TUser'的约束。
I am assuming that this is because the default Identity gremlin is implemented to use IdentityUser<string>
, where I'm using IdentityUser<Guid>
.我假设这是因为默认的 Identity gremlin 被实现为使用
IdentityUser<string>
,我使用的是IdentityUser<Guid>
。
What do I do next?我接下来该怎么做? (I'm all outta ideas)
(我完全没有想法)
Note: I'm building against Microsoft's official .NET Core and ASP.NET Core releases as of Monday (June 27th, 2016) and Visual Studio Update 3 (if that's of any help to anyone)注意:我正在针对截至周一(2016 年 6 月 27 日)和 Visual Studio Update 3(如果这对任何人有帮助)的 Microsoft 官方 .NET Core 和 ASP.NET Core 版本进行构建
Since you're using a custom key type, you must specify it when calling AddEntityFrameworkStores
:由于您使用的是自定义键类型,因此在调用
AddEntityFrameworkStores
时必须指定它:
services
.AddIdentity<User, Role>()
.AddEntityFrameworkStores<ApplicationDbContext, Guid>()
.AddDefaultTokenProviders();
I ended up with this solution:我最终得到了这个解决方案:
Actually I made my own abstract IdentityDbContext
then you can pass any custom model, the only issue is when creating the db EF adds one Disriminator field to all tables other than user and role(inheritance)实际上我做了我自己的抽象
IdentityDbContext
然后你可以传递任何自定义模型,唯一的问题是在创建 db EF 时向除用户和角色(继承)以外的所有表添加一个 Disriminator 字段
public abstract class ApplicationDbContext<TUser, TRole, TKey, TUserClaim, TUserRole, TUserLogin, TRoleClaim, TUserToken> : IdentityDbContext<TUser, TRole, TKey>
where TUser : IdentityUser<TKey>
where TRole : IdentityRole<TKey>
where TKey : IEquatable<TKey>
where TUserClaim : IdentityUserClaim<TKey>
where TUserRole : IdentityUserRole<TKey>
where TUserLogin : IdentityUserLogin<TKey>
where TRoleClaim : IdentityRoleClaim<TKey>
where TUserToken : IdentityUserToken<TKey>
{
public ApplicationDbContext(DbContextOptions options) : base(options) { }
protected ApplicationDbContext() { }
public new DbSet<TRoleClaim> RoleClaims { get; set; }
public new DbSet<TRole> Roles { get; set; }
public new DbSet<TUserClaim> UserClaims { get; set; }
public new DbSet<TUserLogin> UserLogins { get; set; }
public new DbSet<TUserRole> UserRoles { get; set; }
public new DbSet<TUser> Users { get; set; }
public new DbSet<TUserToken> UserTokens { get; set; }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}
public class AppDbContext : ApplicationDbContext<ApplicationUser, ApplicationRole, Guid, ApplicationUserClaim, ApplicationUserRole, ApplicationUserLogin, ApplicationRoleClaim, ApplicationUserToken>
{
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options)
{
}
//public new DbSet<ApplicationUserClaim> 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<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<AppDbContext, Guid>()
.AddDefaultTokenProviders()
.AddUserStore<UserStore<ApplicationUser, ApplicationRole, AppDbContext, Guid>>()
.AddRoleStore<RoleStore<ApplicationRole, AppDbContext, Guid>>()
public class ApplicationUser : IdentityUser<Guid>
{
public ApplicationUser()
{
//this.Id = Guid.NewGuid();
}
public ApplicationUser(string userName) : this() { this.UserName = userName; }
public Guid ClientId { get; set; }
//public new ICollection<ApplicationUserClaim> Claims { get; set; }
}
//public class ApplicationRole : IdentityRole<Guid, ApplicationUserRole, ApplicationRoleClaim>
public class ApplicationRole : IdentityRole<Guid>
{
public ApplicationRole()
{
//this.Id = Guid.NewGuid();
}
public ApplicationRole(string name) : this() { this.Name = name; }
}
public class ApplicationRoleClaim : IdentityRoleClaim<Guid> { }
//[NotMapped]
public class ApplicationUserClaim : IdentityUserClaim<Guid> { }
public class ApplicationUserLogin : IdentityUserLogin<Guid> { }
public class ApplicationUserRole : IdentityUserRole<Guid> { }
public class ApplicationUserToken : IdentityUserToken<Guid> { }
"UserStore`4[TUser,TRole,TContext,TKey]' violates the constraint of type 'TUser'."
“UserStore`4[TUser,TRole,TContext,TKey]' 违反了类型 'TUser' 的约束。”
You need to create a UserStore using the Guid, as well as change your DbContext您需要使用 Guid 创建一个 UserStore,并更改您的 DbContext
public class ApplicationUser : IdentityUser<Guid> { }
public class ApplicationRole : IdentityRole<Guid> { }
public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, ApplicationDbContext, Guid>
{
public ApplicationUserStore(ApplicationDbContext context, IdentityErrorDescriber describer = null) : base(context, describer)
{
}
}
New ApplicationDbContext inherit新的 ApplicationDbContext 继承
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, Guid>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}
In your startup.cs在你的startup.cs
services
.AddIdentity<ApplicationUser, ApplicationRole>()
.AddUserStore<ApplicationUserStore>()
.AddEntityFrameworkStores<ApplicationDbContext, Guid>()
.AddDefaultTokenProviders();
specify Key to .AddEntityFrameworkStore() method in case of using custom User and Role entities.while registering identity in startup在使用自定义用户和角色实体的情况下,指定 Key to .AddEntityFrameworkStore() 方法。同时在启动时注册身份
.AddEntityFrameworkStores<IdentityDbContext, TKey>()
because it uses by default key type string and will cause error in case of other key type.因为它默认使用密钥类型字符串,并且在其他密钥类型的情况下会导致错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.