I am developing a website on ASP.NET Core version 7 and I recently migrated from version 5 to version 7, but this version has given me some challenges. Currently, considering that I have defined an interface for my class, I still get this error
""Error CS0535 'ApplicationUserManager' does not implement interface member 'IApplicationUserManager.NormalizeKey(string)' ""
** It should be noted that I use onion architecture. With the same method, there was no problem in MVC architecture in .NET Core 5 Thank you for your guidance
IApplicationUserManager Codes:
public interface IApplicationUserManager
{
#region BaseClass
IPasswordHasher<User> PasswordHasher { get; set; }
IList<IUserValidator<User>> UserValidators { get; }
IList<IPasswordValidator<User>> PasswordValidators { get; }
ILookupNormalizer KeyNormalizer { get; set; }
IdentityErrorDescriber ErrorDescriber { get; set; }
IdentityOptions Options { get; set; }
bool SupportsUserAuthenticationTokens { get; }
bool SupportsUserAuthenticatorKey { get; }
bool SupportsUserTwoFactorRecoveryCodes { get; }
bool SupportsUserTwoFactor { get; }
bool SupportsUserPassword { get; }
bool SupportsUserSecurityStamp { get; }
bool SupportsUserRole { get; }
bool SupportsUserLogin { get; }
bool SupportsUserEmail { get; }
bool SupportsUserPhoneNumber { get; }
bool SupportsUserClaim { get; }
bool SupportsUserLockout { get; }
bool SupportsQueryableUsers { get; }
IQueryable<User> Users { get; }
Task<string> GenerateConcurrencyStampAsync(User user);
Task<IdentityResult> CreateAsync(User user);
Task<IdentityResult> UpdateAsync(User user);
Task<IdentityResult> DeleteAsync(User user);
Task<User> FindByIdAsync(string userId);
Task<User> FindByNameAsync(string userName);
Task<IdentityResult> CreateAsync(User user, string password);
string NormalizeKey(string key);
Task UpdateNormalizedUserNameAsync(User user);
Task<string> GetUserNameAsync(User user);
Task<IdentityResult> SetUserNameAsync(User user, string userName);
Task<string> GetUserIdAsync(User user);
Task<bool> CheckPasswordAsync(User user, string password);
Task<bool> HasPasswordAsync(User user);
Task<IdentityResult> AddPasswordAsync(User user, string password);
Task<IdentityResult> ChangePasswordAsync(User user, string currentPassword, string newPassword);
Task<IdentityResult> RemovePasswordAsync(User user);
Task<string> GetSecurityStampAsync(User user);
Task<IdentityResult> UpdateSecurityStampAsync(User user);
Task<string> GeneratePasswordResetTokenAsync(User user);
Task<IdentityResult> ResetPasswordAsync(User user, string token, string newPassword);
Task<User> FindByLoginAsync(string loginProvider, string providerKey);
Task<IdentityResult> RemoveLoginAsync(User user, string loginProvider, string providerKey);
Task<IdentityResult> AddLoginAsync(User user, UserLoginInfo login);
Task<IList<UserLoginInfo>> GetLoginsAsync(User user);
Task<IdentityResult> AddClaimAsync(User user, Claim claim);
Task<IdentityResult> AddClaimsAsync(User user, IEnumerable<Claim> claims);
Task<IdentityResult> ReplaceClaimAsync(User user, Claim claim, Claim newClaim);
Task<IdentityResult> RemoveClaimAsync(User user, Claim claim);
Task<IdentityResult> RemoveClaimsAsync(User user, IEnumerable<Claim> claims);
Task<IList<Claim>> GetClaimsAsync(User user);
Task<IdentityResult> AddToRoleAsync(User user, string role);
Task<IdentityResult> AddToRolesAsync(User user, IEnumerable<string> roles);
Task<IdentityResult> RemoveFromRoleAsync(User user, string role);
Task<IdentityResult> RemoveFromRolesAsync(User user, IEnumerable<string> roles);
Task<IList<string>> GetRolesAsync(User user);
Task<bool> IsInRoleAsync(User user, string role);
Task<string> GetEmailAsync(User user);
Task<IdentityResult> SetEmailAsync(User user, string email);
Task<User> FindByEmailAsync(string email);
Task UpdateNormalizedEmailAsync(User user);
Task<string> GenerateEmailConfirmationTokenAsync(User user);
Task<IdentityResult> ConfirmEmailAsync(User user, string token);
Task<bool> IsEmailConfirmedAsync(User user);
Task<string> GenerateChangeEmailTokenAsync(User user, string newEmail);
Task<IdentityResult> ChangeEmailAsync(User user, string newEmail, string token);
Task<string> GetPhoneNumberAsync(User user);
Task<IdentityResult> SetPhoneNumberAsync(User user, string phoneNumber);
Task<IdentityResult> ChangePhoneNumberAsync(User user, string phoneNumber, string token);
Task<bool> IsPhoneNumberConfirmedAsync(User user);
Task<string> GenerateChangePhoneNumberTokenAsync(User user, string phoneNumber);
Task<bool> VerifyChangePhoneNumberTokenAsync(User user, string token, string phoneNumber);
Task<bool> VerifyUserTokenAsync(User user, string tokenProvider, string purpose, string token);
Task<string> GenerateUserTokenAsync(User user, string tokenProvider, string purpose);
void RegisterTokenProvider(string providerName, IUserTwoFactorTokenProvider<User> provider);
Task<IList<string>> GetValidTwoFactorProvidersAsync(User user);
Task<bool> VerifyTwoFactorTokenAsync(User user, string tokenProvider, string token);
Task<string> GenerateTwoFactorTokenAsync(User user, string tokenProvider);
Task<bool> GetTwoFactorEnabledAsync(User user);
Task<IdentityResult> SetTwoFactorEnabledAsync(User user, bool enabled);
Task<bool> IsLockedOutAsync(User user);
Task<IdentityResult> SetLockoutEnabledAsync(User user, bool enabled);
Task<bool> GetLockoutEnabledAsync(User user);
Task<DateTimeOffset?> GetLockoutEndDateAsync(User user);
Task<IdentityResult> SetLockoutEndDateAsync(User user, DateTimeOffset? lockoutEnd);
Task<IdentityResult> AccessFailedAsync(User user);
Task<IdentityResult> ResetAccessFailedCountAsync(User user);
Task<int> GetAccessFailedCountAsync(User user);
Task<IList<User>> GetUsersForClaimAsync(Claim claim);
Task<IList<User>> GetUsersInRoleAsync(string roleName);
Task<string> GetAuthenticationTokenAsync(User user, string loginProvider, string tokenName);
Task<IdentityResult> SetAuthenticationTokenAsync(User user, string loginProvider, string tokenName, string tokenValue);
Task<IdentityResult> RemoveAuthenticationTokenAsync(User user, string loginProvider, string tokenName);
Task<string> GetAuthenticatorKeyAsync(User user);
Task<IdentityResult> ResetAuthenticatorKeyAsync(User user);
string GenerateNewAuthenticatorKey();
Task<IEnumerable<string>> GenerateNewTwoFactorRecoveryCodesAsync(User user, int number);
Task<IdentityResult> RedeemTwoFactorRecoveryCodeAsync(User user, string code);
Task<int> CountRecoveryCodesAsync(User user);
Task<byte[]> CreateSecurityTokenAsync(User user);
#endregion
#region CustomMethod
Task<List<User>> GetAllUsersAsync();
Task<List<UsersViewModel>> GetAllUsersWithRolesAsync();
Task<UsersViewModel> FindUserWithRolesByIdAsync(int UserId);
Task<string> GetFullName(ClaimsPrincipal User);
Task<User> GetUserAsync(ClaimsPrincipal User);
Task<List<UsersViewModel>> GetPaginateUsersAsync(int offset, int limit, bool?
firstnameSortAsc, bool? lastnameSortAsc, bool? emailSortAsc, bool? usernameSortAsc, string
searchText);
#endregion
}
ApplicationUserManager Codes :
public class ApplicationUserManager : UserManager<User>, IApplicationUserManager
{
private readonly ApplicationIdentityErrorDescriber _errors;
private readonly ILookupNormalizer _keyNormalizer;
private readonly ILogger<ApplicationUserManager> _logger;
private readonly IOptions<IdentityOptions> _options;
private readonly IPasswordHasher<User> _passwordHasher;
private readonly IEnumerable<IPasswordValidator<User>> _passwordValidators;
private readonly IServiceProvider _services;
private readonly IUserStore<User> _userStore;
private readonly IEnumerable<IUserValidator<User>> _userValidators;
public ApplicationUserManager(
ApplicationIdentityErrorDescriber errors,
ILookupNormalizer keyNormalizer,
ILogger<ApplicationUserManager> logger,
IOptions<IdentityOptions> options,
IPasswordHasher<User> passwordHasher,
IEnumerable<IPasswordValidator<User>> passwordValidators,
IServiceProvider services,
IUserStore<User> userStore,
IEnumerable<IUserValidator<User>> userValidators)
: base(userStore,options,passwordHasher,userValidators,passwordValidators,keyNormalizer,errors,services,logger)
{
_userStore = userStore;
_errors = errors;
_logger = logger;
_services = services;
_passwordHasher = passwordHasher;
_userValidators = userValidators;
_options = options;
_keyNormalizer = keyNormalizer;
_passwordValidators = passwordValidators;
}
public async Task<List<User>> GetAllUsersAsync()
{
return await Users.ToListAsync();
}
public async Task<List<UsersViewModel>> GetAllUsersWithRolesAsync()
{
return await Users.Select(user => new UsersViewModel
{
Id = user.Id,
Email = user.Email,
UserName = user.UserName,
PhoneNumber = user.PhoneNumber,
FirstName = user.FirstName,
LastName = user.LastName,
BirthDate = user.BirthDate,
IsActive = user.IsActive,
Image = user.Image,
RegisterDateTime = user.RegisterDateTime,
Roles=user.Roles.Select(u=>u.Role.Name),
}).ToListAsync();
}
public async Task<UsersViewModel> FindUserWithRolesByIdAsync(int UserId)
{
return await Users.Where(u => u.Id == UserId).Select(user => new UsersViewModel
{
Id = user.Id,
Email = user.Email,
UserName = user.UserName,
PhoneNumber = user.PhoneNumber,
FirstName = user.FirstName,
LastName = user.LastName,
BirthDate = user.BirthDate,
IsActive = user.IsActive,
Image = user.Image,
RegisterDateTime = user.RegisterDateTime,
Roles = user.Roles.Select(u => u.Role.Name),
AccessFailedCount = user.AccessFailedCount,
EmailConfirmed = user.EmailConfirmed,
LockoutEnabled = user.LockoutEnabled,
LockoutEnd = user.LockoutEnd,
PhoneNumberConfirmed = user.PhoneNumberConfirmed,
TwoFactorEnabled = user.TwoFactorEnabled,
}).FirstOrDefaultAsync();
}
public async Task<string> GetFullName(ClaimsPrincipal User)
{
var UserInfo = await GetUserAsync(User);
return UserInfo.FirstName + " " + UserInfo.LastName;
}
public async Task<List<UsersViewModel>> GetPaginateUsersAsync(int offset, int limit, bool? firstnameSortAsc, bool? lastnameSortAsc, bool? emailSortAsc, bool? usernameSortAsc, string searchText)
{
var users = await Users.Include(u => u.Roles).Where(t=>t.FirstName.Contains(searchText) || t.LastName.Contains(searchText) || t.Email.Contains(searchText) || t.PhoneNumber.Contains(searchText))
.Select(user => new UsersViewModel
{
Id = user.Id,
Email = user.Email,
UserName = user.UserName,
PhoneNumber = user.PhoneNumber,
FirstName = user.FirstName,
LastName = user.LastName,
IsActive = user.IsActive,
Image = user.Image,
}).Skip(offset).Take(limit).ToListAsync();
if (firstnameSortAsc != null)
{
users = users.OrderBy(t => (firstnameSortAsc == true && firstnameSortAsc != null) ? t.FirstName : "").OrderByDescending(t => (firstnameSortAsc == false && firstnameSortAsc != null) ? t.FirstName : "").ToList();
}
else if (lastnameSortAsc != null)
{
users = users.OrderBy(t => (lastnameSortAsc == true && lastnameSortAsc != null) ? t.LastName : "").OrderByDescending(t => (lastnameSortAsc == false && lastnameSortAsc != null) ? t.LastName : "").ToList();
}
else if (emailSortAsc != null)
{
users = users.OrderBy(t => (emailSortAsc == true && emailSortAsc != null) ? t.Email : "").OrderByDescending(t => (emailSortAsc == false && emailSortAsc != null) ? t.Email : "").ToList();
}
else if (usernameSortAsc != null)
{
users = users.OrderBy(t => (usernameSortAsc == true && usernameSortAsc != null) ? t.PhoneNumber : "").OrderByDescending(t => (usernameSortAsc == false && usernameSortAsc != null) ? t.UserName : "").ToList();
}
foreach (var item in users)
item.Row = ++offset;
return users;
}
}
According to your description, you don't use separate interface and implementation method like this in .Net Core 5, so I'm not sure why it works in .Net Core 5.
However, your error message says it all, you have not implemented IApplicationUserManager
's string NormalizeKey(string key);
in ApplicationUserManager
, this is not included in UserManager<User>
, UserManager<TUser>.NormalizeKey(String) Method
is only applicable to .Net Core 2.2 and lower versions. So you need to implement it separately in ApplicationUserManager
:
public string NormalizeKey(string key)
{
return "A String";
}
Of course, if you don’t need NormalizeKey
, you can also remove the string NormalizeKey(string key);
from the IApplicationUserManager
interface.