为什么这违反了类型参数"TUser"的约束?



我试图自定义asp.net身份实体与以下几个:

public class User : IdentityUser<string, UserClaim, UserRole, UserLogin>
public class UserClaim : IdentityUserClaim<string>
public class UserLogin : IdentityUserLogin<string>
public class UserRole : IdentityUserRole<string>
public class UserToken : IdentityUserToken<string>
public class Role : IdentityRole<string, UserRole, RoleClaim>
public class RoleClaim : IdentityRoleClaim<string>

然后我创建了一个DbContext类,如下所示

public class AppDbContext : IdentityDbContext<User, Role, string, UserClaim, UserRole, UserLogin, RoleClaim, UserToken>

然后用

配置
services
    .AddIdentity<User, Role>()
    .AddEntityFrameworkStores<AppDbContext>()
    .AddDefaultTokenProviders();

但我也尝试过

.AddEntityFrameworkStores<AppDbContext, string>()

我在互联网上读过很多博客文章,比如这个,但是他们中的大多数都必须处理键的数据类型的变化,比如intGuid。在我的情况下,我没有从string更改默认密钥数据类型。

在所有这些情况下,编译都是正常的,但在运行

时抛出错误。

系统。TypeLoadExceptionGenericArguments[0],"MyIdentity.Entities。用户',"Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore"8[摘要、TRole TContext, TKey, TUserClaim, TUserRole, TUserLogin, TUserToken)"违反了类型参数"TUser"的约束。

在System.RuntimeTypeHandle

。实例化(RuntimeTypeHandle处理,IntPtr* pInst, int numGenericArgs, ObjectHandleOnStack类型)atSystem.RuntimeTypeHandle。实例化(Type[] inst)System.RuntimeType。MakeGenericType(类型[]实例化)

如果我像这篇文章中解释的那样添加一个自定义的UserStore

public class UserStore : UserStore<User, Role, AppDbContext, string, UserClaim, UserRole, UserLogin, UserToken>

出现编译错误,提示

CS0311类型MyIdentity.Entities。"角色"不能用作类型泛型类型中的参数"TRole"或方法"UserStore"。没有隐含的引用转换"MyIdentity.Entities。角色的"Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole>的

我做错了什么?

我面对这个问题,我发现这个:"当你自定义ASP。. NET Core Identity,你不应该再使用AddEntityFrameworkStores。你应该实现你的:

public class ApplicationRoleManager:  RoleManager<Role>
public class ApplicationRoleStore :  RoleStore<Role, ApplicationDbContext, int, UserRole, RoleClaim>
public class ApplicationSignInManager :  SignInManager<User>
public class ApplicationUserManager : UserManager<User>
public class ApplicationUserStore : UserStore<User, Role, ApplicationDbContext, int, UserClaim, UserRole, UserLogin, UserToken, RoleClaim>
然后将内置服务重定向到您的自定义服务(Startup.cs):
services.AddScoped<UserStore<User, Role, ApplicationDbContext, int, UserClaim, UserRole, UserLogin, UserToken, RoleClaim>, ApplicationUserStore> ();
services.AddScoped<UserManager<User>, ApplicationUserManager>();
services.AddScoped<RoleManager<Role>, ApplicationRoleManager>();
services.AddScoped<SignInManager<User>, ApplicationSignInManager>();
services.AddScoped<RoleStore<Role, ApplicationDbContext, int, UserRole, RoleClaim>, ApplicationRoleStore>();
services.AddScoped<IEmailSender, AuthMessageSender>();
services.AddScoped<ISmsSender, AuthMessageSender>();

然后介绍您的定制服务:

services.AddIdentity<User, Role>(identityOptions =>
{
 // ...
 }).AddUserStore<ApplicationUserStore>()
   .AddUserManager<ApplicationUserManager>()
   .AddRoleStore<ApplicationRoleStore>()
   .AddRoleManager<ApplicationRoleManager>()
   .AddSignInManager<ApplicationSignInManager>()
   // You **cannot** use .AddEntityFrameworkStores() when you customize everything
   //.AddEntityFrameworkStores<ApplicationDbContext, int>()
   .AddDefaultTokenProviders();
  • 根据MSDN, UserStore<TUser>的约束是TUser : IdentityUser
  • 同样根据MSDN, IdentityUser : IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim> .
  • 根据你方申报,User : IdentityUser<string, UserClaim, UserRole, UserLogin> .

冗长的名称很容易被忽略,所以我们将IdentityUser别名为D,将IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>别名为B。现在上面的代码可以重新表述为:

  • TUser : D (TUser必须是D的一种)
  • D : B (DB的一类)
  • User : B(根据要求,您的User一般是B的一种,而不是特定的D)

这里的问题是RoleClaim必须是IdentityRoleClaim<TKey>类型

 where TRole : IdentityRole<TKey, TUserRole, IdentityRoleClaim<TKey>>

代替TRoleClaim

where TRole : IdentityRole<TKey, TUserRole, TRoleClaim>

此处报告为bug

相关内容

  • 没有找到相关文章

最新更新