使用 IdentityDbContext 进行 asp.net core 身份验证<AppUser, AppRole, int, AppUserClaim, AppUserRole, AppUserLogin, AppRoleClaim, AppUserToken>

问题描述 投票:0回答:3

我正在尝试从代码优先模型创建数据库。当我运行

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.
asp.net-mvc entity-framework asp.net-core entity-framework-6
3个回答
4
投票

您的问题是由

.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
版本。当我弄清楚一切后,我将在这里更新更多代码。


0
投票

this is how i did it on my project


-1
投票

当您自定义 ASP.NET Core Identity 时,不应使用 不再添加EntityFrameworkStores。因为它会覆盖你所有的 以前的设置和自定义为默认身份服务。

引用Github的答案这里

© www.soinside.com 2019 - 2024. All rights reserved.