[英]ASP.NET Core - custom AspNetCore.Identity implementation not working
[英]AspNetCore.Identity not working with custom User/Role implementation
因為我傾向於使用Guid
作為我的主鍵類型,所以我的User
和Role
類實現如下
public class User : IdentityUser<Guid, UserClaim, UserRole, UserLogin>
{
}
public class Role : IdentityRole<Guid, UserRole, RoleClaim>
{
}
請注意, UserClaim
、 UserRole
、 UserLogin
和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 版本進行構建
由於您使用的是自定義鍵類型,因此在調用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.