簡體   English   中英

AspNetCore.Identity 不適用於自定義用戶/角色實現

[英]AspNetCore.Identity not working with custom User/Role implementation

因為我傾向於使用Guid作為我的主鍵類型,所以我的UserRole類實現如下

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

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

請注意, UserClaimUserRoleUserLoginRoleClaim都以相同的方式實現

這是我的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 版本進行構建

由於您使用的是自定義鍵類型,因此在調用AddEntityFrameworkStores時必須指定它:

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

我最終得到了這個解決方案:
實際上我做了我自己的抽象IdentityDbContext然后你可以傳遞任何自定義模型,唯一的問題是在創建 db 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> { }

“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();

在使用自定義用戶和角色實體的情況下,指定 Key to .AddEntityFrameworkStore() 方法。同時在啟動時注冊身份

.AddEntityFrameworkStores<IdentityDbContext, TKey>()

因為它默認使用密鑰類型字符串,並且在其他密鑰類型的情況下會導致錯誤。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM