為什麼這違反了類型參數“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>()我在網際網路上閱讀了許多部落格文章,例如這樣,但其中大多數必須處理鍵的數據類型更改,例如 to
int或Guid. 在我的情況下,我沒有將預設鍵數據類型從string.在所有這些情況下,編譯都可以,但是在執行時會引發錯誤
System.TypeLoadException GenericArguments
$$ 0 $$,‘MyIdentity.Entities.User’,在’Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`8$$ TUser,TRole,TContext,TKey,TUserClaim,TUserRole,TUserLogin,TUserToken $$’ 違反了類型參數 ‘TUser’ 的約束。 在 System.RuntimeTypeHandle.Instantiate(RuntimeTypeHandle 句柄,IntPtr* pInst,int numGenericArgs,ObjectHandleOnStack 類型)在 System.RuntimeTypeHandle.Instantiate(類型
$$ $$inst) 在 System.RuntimeType.MakeGenericType(Type$$ $$實例化)
如果我像這篇文章
UserStore中解釋的那樣添加一個自定義類public class UserStore : UserStore<User, Role, AppDbContext, string, UserClaim, UserRole, UserLogin, UserToken>出現編譯錯誤,說明
CS0311 類型“MyIdentity.Entities.Role”不能用作泛型類型或方法“UserStore”中的類型參數“TRole”。沒有從“MyIdentity.Entities.Role”到“Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole>”的隱式引用轉換
我做錯了什麼?
- 根據 MSDN,約束
UserStore<TUser>為TUser : IdentityUser。- 同樣根據
IdentityUser : IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>MSDN ,.- 根據您的聲明,
User : IdentityUser<string, UserClaim, UserRole, UserLogin>.長名字很容易被忽略,所以讓我們別名
IdentityUserasD和IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>asB。現在可以將上面的內容重新表述為:
TUser : D(aTUser必須是一種D)D : B(D是一種B)User : B(根據需要,您User是B一般的但不是D具體的)
我遇到了這個問題,我發現:“當您自定義 ASP.NET Core 標識時,您不應再使用 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();