ASP.NET核心标识:基类(IdentityUser,IdentityRole,IdentityUserRole e.t.c.)实现

时间:2016-08-22 18:49:55

标签: asp.net entity-framework asp.net-core asp.net-identity entity-framework-core

上下文:

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'类型的约束。

Exception img 如何解决这个问题呢?需要“UserRoleRoleClaim”类。

2 个答案:

答案 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作为主键。