Reputation: 135
Using Blazor server, dotnet 5 and Entity Framework Core, I have successfully customised Identity using integer IDs
e.g
public class ApplicationUser : IdentityUser<int>
{
[Required]
[MaxLength(50)]
public string FirstName { get; set; }
[Required]
[MaxLength(50)]
public string LastName { get; set; }
}
I now want to extend UserStore for custom login to store password history to prevent duplication. The documented way of doing this seems to be:
public class ApplicationUserStore : UserStore<ApplicationUser>
{
public ApplicationUserStore(ApplicationDbContext context, IdentityErrorDescriber describer = null) : base(context, describer)
{
}
public override async Task<IdentityResult> CreateAsync(ApplicationUser appUser)
{
await base.CreateAsync(appUser);
await AddToUsedPasswordAsync(appUser, appUser.PasswordHash);
}
public Task AddToUsedPasswordAsync(ApplicationUser appuser, string userpassword)
{
appuser.UserUsedPassword.Add(new UsedPassword() { UserID = appuser.Id, HashPassword = userpassword });
return UpdateAsync(appuser);
}
}
This works for the default GUID Id but when using an integer it throws the error:
The type ApplicationUser cannot be used as type parameter 'TUser' in the generic type or method 'UserStore'. There is no implicit reference conversion from ApplicationUser' to 'Microsoft.AspNetCore.Identity.IdentityUser'.
What is the correct way to do this?
EDIT:
Per @Yinqiu, modified for custom ApplicationRole to
public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, ApplicationDbContext, int> {
public ApplicationUserStore(ApplicationDbContext context, IdentityErrorDescriber describer = null) : base(context, describer)
{
}
Builds successfully and creates users but gives run time error when trying to access ApplicationUserManager.IsInRoleAsync:
{"Cannot create a DbSet for 'IdentityUserRole' because this type is not included in the model for the context."}
However I have a custom User Role:
public class ApplicationUserRole : IdentityUserRole<int>
{
public ApplicationUserRole() : base() { }
public bool IsSystemEssential { get; set; }
}
With a definition in ApplicationDbContext :
public DbSet ApplicationUserRoles { get; set; }
Upvotes: 1
Views: 787
Reputation: 135
SOLVED (provisionally)
After looking at the overloaded inheritance options you have to extend as follows:
public class ApplicationUserStore : UserStore<ApplicationUser, ApplicationRole, ApplicationDbContext, int, ApplicationUserClaim, ApplicationUserRole, ApplicationUserLogin, ApplicationUserToken, ApplicationRoleClaim>
{
public ApplicationUserStore(ApplicationDbContext context, IdentityErrorDescriber describer = null) : base(context, describer)
{
}
}
This seems to work. Still need to check all role and claim updates.
Upvotes: 2
Reputation: 7190
You can change your ApplicationUserStore
as following.
public class ApplicationUserStore : UserStore<ApplicationUser,IdentityRole<int>, ApplicationDbContext,int>
{
public ApplicationUserStore(ApplicationDbContext context, IdentityErrorDescriber describer = null) : base(context, describer)
{
}
//...
}
Upvotes: 1