What is _userManager? Maybe you should set or clear its KeyNormalizer.
Identity - forcing the Normalized Email & Username to lower case

This is really weird.
I call the following (in a unit test hence the calling async methods as sync):
var identityUser = new IdentityUser(email)
{
Email = email,
PhoneNumber = phone
};
identityUser.NormalizedEmail = identityUser.Email.Normalize().ToUpperInvariant();
identityUser.NormalizedUserName = identityUser.UserName?.Normalize().ToUpperInvariant();
// activate user
identityUser.EmailConfirmed = true;
identityUser.PhoneNumberConfirmed = true;
identityUser.LockoutEnabled = false;
var result = _store.SetUserNameAsync(identityUser, identityUser.Email, CancellationToken.None);
result.Wait();
if (!result.IsCompletedSuccessfully)
throw new Exception($"Failed to create username {identityUser.UserName}: {result.Exception?.Message}");
var identityCreateResult = _userManager.CreateAsync(identityUser, password).Result;
if (!identityCreateResult.Succeeded)
throw new Exception($"Failed to create user {identityUser.UserName}: {identityCreateResult.Errors.First().Description}");
And on exit from _userManager.CreateAsync(identityUser, password)
the NormalizedEmail and NormalizedUserName in identityUser are now lowercase. And in the database they are lower case.
Ok, so I then "fix" it with the following:
identityUser = identityContext.Users.First(x => x.Id == identityUser.Id);
identityUser.NormalizedEmail = identityUser.Email.ToUpperInvariant();
identityUser.NormalizedUserName = identityUser.UserName?.ToUpperInvariant();
// activate user
identityUser.EmailConfirmed = true;
identityUser.PhoneNumberConfirmed = true;
identityUser.LockoutEnabled = false;
identityContext.SaveChanges();
And now the identityUser object and the database has them in upper case until I call the following:
var claim = new Claim("Manager", "_states");
_ = _userManager.AddClaimAsync(identityUser, claim).Result;
On exit from _userManager.AddClaimAsync(identityUser, claim).Result
both the identityUser object and the database now have them as lower case.
What in the world is going on here? All the documentation says the Normalized properties are the regular property with Normalize().ToUpperInvariant()
applied to them. This makes no sense.
More details:
var optionsIdentityBuilder = new DbContextOptionsBuilder<UserDbContext>();
optionsIdentityBuilder.UseSqlServer(identityConnectionString);
using var dbIdentityContext = new UserDbContext(optionsIdentityBuilder.Options);
_store = new UserStore<IdentityUser>(dbIdentityContext);
_userManager = new UserManager<IdentityUser>(_store, null!, new PasswordHasher<IdentityUser>(),
null!, null!, null!, null!, null!, null!);
And after calling the above I looked at _userManager.KeyNormalizer
and it has a value of null. So I added the following line (h/t @Viorel ):
_userManager.KeyNormalizer = new UpperInvariantLookupNormalizer();
And now it works.
So that fixes it. But it does leave the follow on question - should that be the default setting?
thanks - dave