I am trying to customize asp.net identity entities with the following ones:
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>
I have then created a DbContext class like the following
public class AppDbContext : IdentityDbContext<User, Role, string, UserClaim, UserRole, UserLogin, RoleClaim, UserToken>
And then configure these with
services
.AddIdentity<User, Role>()
.AddEntityFrameworkStores<AppDbContext>()
.AddDefaultTokenProviders();
but I have tried also with
.AddEntityFrameworkStores<AppDbContext, string>()
I have read many blog posts on the internet, like this for example, but most of them have to deal against a change of data type for the keys, like to int
or Guid
. In my case I am not changing the default key datatype from string
.
I all these cases the compile is ok but it throws an error when running
System.TypeLoadException GenericArguments[0],'MyIdentity.Entities.User', on 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.UserStore`8[TUser,TRole,TContext,TKey,TUserClaim,TUserRole,TUserLogin,TUserToken]' violates the constraint of type parameter 'TUser'.
at System.RuntimeTypeHandle.Instantiate(RuntimeTypeHandle handle, IntPtr* pInst, int numGenericArgs, ObjectHandleOnStack type) at System.RuntimeTypeHandle.Instantiate(Type[] inst) at System.RuntimeType.MakeGenericType(Type[] instantiation)
If I add a customized UserStore
class like explained in this post
public class UserStore : UserStore<User, Role, AppDbContext, string, UserClaim, UserRole, UserLogin, UserToken>
A compile error appear saying that
CS0311 The type 'MyIdentity.Entities.Role' cannot be used as type parameter 'TRole' in the generic type or method 'UserStore'. There is no implicit reference conversion from 'MyIdentity.Entities.Role' to 'Microsoft.AspNetCore.Identity.EntityFrameworkCore.IdentityRole>'
What I am doing wrong?
I faced this issue, i found this: "When you are customizing ASP.NET Core Identity, you should not use AddEntityFrameworkStores anymore." you should implement yours:
And Then redirect built-in services to your custom services (Startup.cs):
Then introduce your custom services:
The problem is here
RoleClaim
must be of typeIdentityRoleClaim<TKey>
instead of
TRoleClaim
It's reported here as a bug.
UserStore<TUser>
isTUser : IdentityUser
.IdentityUser : IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
.User : IdentityUser<string, UserClaim, UserRole, UserLogin>
.The long names make it easy to miss, so let's alias
IdentityUser
asD
andIdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>
asB
. Now the above can be restated as:TUser : D
(aTUser
must be a kind ofD
)D : B
(D
is a kind ofB
)User : B
(yourUser
is a kind ofB
in general but not a kind ofD
specifically, as required)