我正在尝试从代码优先模型创建数据库。当我运行
dotnet ef migrations add
或调试应用程序时,出现错误:
TypeLoadException: GenericArguments[0], 'OpPISWeb.Models.AppUser', on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9[TUser,TRole,TContext,TKey,TUserClaim,TUserRole,TUserLogin,TUserToken,TRoleClaim]' violates the constraint of type parameter 'TUser'.
System.RuntimeTypeHandle.Instantiate(RuntimeTypeHandle handle, IntPtr* pInst, int numGenericArgs, ObjectHandleOnStack type)
代码:
.AddEntityFrameworkStores<AppWebContext, int>()
我在ConfigureServices中的代码是:
var res = services
.AddIdentity<AppUser, AppRole>(config =>
{
config.User.RequireUniqueEmail = true;
config.Password.RequireNonAlphanumeric = false;
config.Cookies.ApplicationCookie.AutomaticChallenge = false;
})
.AddEntityFrameworkStores<AppWebContext, int>()
.AddDefaultTokenProviders();
我的 EF 型号是:
[Table("Roles")]
public partial class AppRole : IdentityRole<int, AppUserRole, AppRoleClaim>
{
}
[Table("RoleClaims")]
public partial class AppRoleClaim : IdentityRoleClaim<int>
{
}
[Table("Users")]
public partial class AppUser : IdentityUser<int, AppUserClaim, AppUserRole, AppUserLogin>
{
}
//same for UserClaim, UserLogin, UserRole, UserToken
和我的 DBContext:
public partial class AppWebContext : IdentityDbContext<AppUser, AppRole, int, AppUserClaim, AppUserRole, AppUserLogin, AppRoleClaim, AppUserToken>
{
public AppWebContext() : base() {
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(@"Server=...");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<AppUser>(entity =>
{
entity
.HasKey(u => u.Id);
entity.Property(p => p.Id)
.ValueGeneratedOnAdd();
});
modelBuilder.Entity<AppRole>(entity =>
{
entity
.HasKey(u => u.Id);
entity.Property(p => p.Id)
.ValueGeneratedOnAdd();
});
modelBuilder.Entity<AppUserClaim>(entity =>
{
entity
.HasKey(u => u.Id);
entity.Property(p => p.Id)
.ValueGeneratedOnAdd();
});
modelBuilder.Entity<AppUserRole>(entity =>
{
entity
.HasKey(u => new { u.RoleId, u.UserId });
});
modelBuilder.Entity<AppRoleClaim>(entity =>
{
entity
.HasKey(u => u.Id);
entity.Property(p => p.Id)
.ValueGeneratedOnAdd();
});
}
}
我错过了什么?我是 ASP.net 和 ASP.NET Core 的新手。
我使用的是1.1版本。
完全错误:
An error occurred while starting the application.
TypeLoadException: GenericArguments[0], 'OpPISWeb.Models.AppUser', on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9[TUser,TRole,TContext,TKey,TUserClaim,TUserRole,TUserLogin,TUserToken,TRoleClaim]' violates the constraint of type parameter 'TUser'.
System.RuntimeTypeHandle.Instantiate(RuntimeTypeHandle handle, IntPtr* pInst, int numGenericArgs, ObjectHandleOnStack type)
ArgumentException: GenericArguments[0], 'OpPISWeb.Models.AppUser', on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`4[TUser,TRole,TContext,TKey]' violates the constraint of type 'TUser'.
System.RuntimeType.ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
TypeLoadException: GenericArguments[0], 'OpPISWeb.Models.AppUser', on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`9[TUser,TRole,TContext,TKey,TUserClaim,TUserRole,TUserLogin,TUserToken,TRoleClaim]' violates the constraint of type parameter 'TUser'.
System.RuntimeTypeHandle.Instantiate(RuntimeTypeHandle handle, IntPtr* pInst, int numGenericArgs, ObjectHandleOnStack type)
System.RuntimeTypeHandle.Instantiate(Type[] inst)
System.RuntimeType.MakeGenericType(Type[] instantiation)
Show raw exception details
ArgumentException: GenericArguments[0], 'OpPISWeb.Models.AppUser', on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`4[TUser,TRole,TContext,TKey]' violates the constraint of type 'TUser'.
System.RuntimeType.ValidateGenericArguments(MemberInfo definition, RuntimeType[] genericArguments, Exception e)
System.RuntimeType.MakeGenericType(Type[] instantiation)
Microsoft.Extensions.DependencyInjection.IdentityEntityFrameworkBuilderExtensions.GetDefaultServices(Type userType, Type roleType, Type contextType, Type keyType)
Microsoft.Extensions.DependencyInjection.IdentityEntityFrameworkBuilderExtensions.AddEntityFrameworkStores<TContext, TKey>(IdentityBuilder builder)
OpPISWeb.Startup.ConfigureServices(IServiceCollection services)
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services)
Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices()
Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
Show raw exception details
.NET Core X64 v4.1.1.0 | Microsoft.AspNetCore.Hosting version 1.1.0-rtm-22752 | Microsoft Windows 10.0.14393 | Need help? - Yes I do. Please.
您的问题是由
.AddEntityFrameworkStores<AppWebContext, int>()
引起的。看看Haok 在本文末尾的回复:
https://github.com/aspnet/Identity/issues/1001。
特别是这2个
“只能使用从 IdentityUser 派生的用户来调用 AddEntityFrameworkStores。如果您要指定更通用的参数,请改用 IdentityBuilder.AddUserStore()。”
“只能使用从 IdentityRole 派生的角色来调用 AddEntityFrameworkStores。如果要指定更通用的参数,请改用 IdentityBuilder.AddRoleStore()。”
因此,如果您想覆盖
UserClaim
、UserLogin
和所有其他,您需要实现自己的 UserStore
和 RoleStore
,并使用 AddUserStore<T>()
和 AddRoleStore<T>()
而不是 AddEntityFrameworkStores
。
应用程序用户商店
public class AppUserStore : UserStore<AppUser, AppRole, AppDbContext, int, AppUserClaim, AppUserRole, AppUserLogin, AppUserToken, AppRoleClaim>
{
public AppUserStore(AppDbContext dbContext)
: base(dbContext)
{
}
protected override AppUserToken CreateUserToken(AppUser user, string loginProvider, string name, string value)
{
throw new NotImplementedException();
}
protected override AppUserLogin CreateUserLogin(AppUser user, UserLoginInfo login)
{
throw new NotImplementedException();
}
protected override AppUserRole CreateUserRole(AppUser user, AppRole role)
{
throw new NotImplementedException();
}
protected override AppUserClaim CreateUserClaim(AppUser user, Claim claim)
{
throw new NotImplementedException();
}
}
应用程序角色商店
public class AppRoleStore : RoleStore<AppRole, AppDbContext, int, AppUserRole, AppRoleClaim>
{
public AppRoleStore(AppDbContext dbContext)
: base(dbContext)
{
}
protected override AppRoleClaim CreateRoleClaim(AppRole role, Claim claim)
{
throw new NotImplementedException();
}
}
在你的
Startup.cs
中:
services.AddIdentity<AppUser, AppRole>()
.AddUserStore<AppUserStore>()
.AddRoleStore<AppRoleStore>()
// Components that generate the confirm email and reset password tokens
.AddDefaultTokenProviders();
现在我确实认为您还需要创建自己的
UserManager
、RoleManager
和 SignInManager
版本。当我弄清楚一切后,我将在这里更新更多代码。
当您自定义 ASP.NET Core Identity 时,不应使用 不再添加EntityFrameworkStores。因为它会覆盖你所有的 以前的设置和自定义为默认身份服务。
引用Github的答案这里。