public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, Guid, UserClaim, UserRole,
UserLogin, RoleClaim, UserToken>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
}
}
public class ApplicationUser : IdentityUser<Guid, UserClaim, UserRole, UserLogin>
{
}
public class ApplicationRole : IdentityRole<Guid, UserRole, RoleClaim>
{
}
public class UserRole : IdentityUserRole<Guid>
{
}
public class RoleClaim : IdentityRoleClaim<Guid>
{
}
public class UserClaim : IdentityUserClaim<Guid>
{
}
public class UserLogin : IdentityUserLogin<Guid>
{
}
public class UserToken : IdentityUserToken<Guid>
{
}
Startup.cs
: services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<ApplicationDbContext, Guid>()
.AddDefaultTokenProviders();
当应用程序启动时,它会抛出以下异常:
GenericArguments [0],'del.Models.ApplicationUser',on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`4 [TUSER,TRole,TContext,TKEY的]' 违反了'TUser'类型的约束。
如何解决这个问题呢?需要“UserRole
,RoleClaim
”类。
答案 0 :(得分:2)
我今天遇到了同样的问题。我正在大力扩展Identity系统,以支持我在我的应用程序中需要的东西。我注意到的一件事是,由于IdentityUser有很多不同的派生类,因此它并不总是像覆盖&#34; IdentityUser&lt;&gt;&#34;那样简单。
话虽如此,例外情况是在ExtensionMethod&#34; AddEntityFrameworkStores()&#34;中被抛出。原因是该扩展方法还使用动态创建泛型类型的私有帮助器方法:
userStoreType = typeof(UserStore<,,,>).MakeGenericType(userType, roleType, contextType, keyType);
UserStore&LT;&GT;还有很多不同的通用签名。我创建了自己的派生UserStore(ApplicationUserStore),以便我可以创建自己的ApplicationUserRole。在这样做时,泛型类型的创建将不再有效。我必须创建自己的扩展方法版本:
userStoreType = typeof(ApplicationUserStore<,,,>).MakeGenericType(userType, roleType, contextType, keyType);
现在,这不是你的&#34;确切的&#34;问题,但我99%确定这就是它。您可能需要使用以下签名创建自己的派生UserStore:
public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, ApplicationDbContext, Guid>
{
...
}
然后创建一个新的Extensions方法类,它复制原始文件,但更改了UserStore的创建。
public static class IdentityEntityFrameworkBuilderExtensions2
{
public static IdentityBuilder AddEntityFrameworkStores2<TContext>(this IdentityBuilder builder)
where TContext : DbContext
{
builder.Services.TryAdd(GetDefaultServices(builder.UserType, builder.RoleType, typeof(TContext)));
return builder;
}
public static IdentityBuilder AddEntityFrameworkStores2<TContext, TKey>(this IdentityBuilder builder)
where TContext : DbContext
where TKey : IEquatable<TKey>
{
builder.Services.TryAdd(GetDefaultServices(builder.UserType, builder.RoleType, typeof(TContext), typeof(TKey)));
return builder;
}
private static IServiceCollection GetDefaultServices(Type userType, Type roleType, Type contextType, Type keyType = null)
{
Type userStoreType;
Type roleStoreType;
keyType = keyType ?? typeof(string);
userStoreType = typeof(ApplicationUserStore<,,,>).MakeGenericType(userType, roleType, contextType, keyType);
roleStoreType = typeof(ApplicationRoleStore<,,>).MakeGenericType(roleType, contextType, keyType);
var services = new ServiceCollection();
services.AddScoped(
typeof(IUserStore<>).MakeGenericType(userType),
userStoreType);
services.AddScoped(
typeof(IRoleStore<>).MakeGenericType(roleType),
roleStoreType);
return services;
}
}
希望这会有所帮助。
答案 1 :(得分:0)
Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore
如下(source):
public class UserStore<TUser>
: UserStore<TUser, IdentityRole, DbContext, string>,
IUserLoginStore<TUser>,
IUserRoleStore<TUser>,
IUserClaimStore<TUser>,
IUserPasswordStore<TUser>,
IUserSecurityStampStore<TUser>,
IUserEmailStore<TUser>,
IUserLockoutStore<TUser>,
IUserPhoneNumberStore<TUser>,
IQueryableUserStore<TUser>,
IUserTwoFactorStore<TUser>,
IUserAuthenticationTokenStore<TUser>,
IUserStore<TUser>,
IDisposable
where TUser : IdentityUser<string>, new ()
注意TUser
约束,TUser
必须为IdentityUser<string>
,或者它应来自IdentityUser<string>
。在您的情况下,您声明ApplicationUser
来自IdentityUser<Guid, UserClaim, UserRole, UserLogin>
。这是例外的原因。您应该使用string
作为主键。