AspNetCore.Identity无法使用自定义用户/角色实现

时间:2016-07-04 08:08:57

标签: c# entity-framework asp.net-core .net-core

由于我倾向于将Guid作为我的主键类型,因此我的UserRole类实现如下

public class User : IdentityUser<Guid, UserClaim, UserRole, UserLogin>
{
}

public class Role : IdentityRole<Guid, UserRole, RoleClaim>
{
}

请注意UserClaimUserRoleUserLogin&amp; RoleClaim都以相同的方式实施

这是我的DbContext实施

public class ApplicationDbContext : IdentityDbContext<User, Role, Guid, UserClaim, UserRole, UserLogin, RoleClaim, UserToken>
{
}

到目前为止一切都很好,除了AspNetCore的新DI容器默认情况下似乎不喜欢我的自定义实现。我的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的]'   违反了'TUser'类型的约束。

我假设这是因为默认的Identity gremlin被实现为使用IdentityUser<string>,我正在使用IdentityUser<Guid>

接下来我该怎么办? (我完全没有想法)

注意:我正在构建截至周一(2016年6月27日)和Visual Studio Update 3(如果对任何人有任何帮助)的Microsoft官方.NET Core和ASP.NET Core版本

4 个答案:

答案 0 :(得分:5)

由于您使用的是自定义密钥类型,因此在调用AddEntityFrameworkStores时必须指定该类型:

services
    .AddIdentity<User, Role>()
    .AddEntityFrameworkStores<ApplicationDbContext, Guid>()
    .AddDefaultTokenProviders();

答案 1 :(得分:4)

我最终得到了这个解决方案:
实际上我做了我自己的摘要IdentityDbContext然后你可以传递任何自定义模型,唯一的问题是在创建数据库时,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> { }

答案 2 :(得分:0)

  

“UserStore`4 [TUser,TRole,TContext,TKey]'违反了   输入'TUser'。“

您需要使用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)
    {
    }
}

新的ApplicationDbContext继承

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, Guid>
{
    public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options) { }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);
    }
}

在你的startup.cs

services
    .AddIdentity<ApplicationUser, ApplicationRole>()
    .AddUserStore<ApplicationUserStore>()
    .AddEntityFrameworkStores<ApplicationDbContext, Guid>()
    .AddDefaultTokenProviders();

答案 3 :(得分:0)

在使用自定义用户和角色实体时指定.AddEntityFrameworkStore()方法的键。在启动时注册身份

.AddEntityFrameworkStores<IdentityDbContext, TKey>()

因为它默认使用密钥类型字符串,并且在其他密钥类型的情况下会导致错误。