I'm trying to set the UserValidator
for the default ApplicationUserManager
in a new ASP.NET MVC 5 project (using ASP.NET Identity 2). I've created a very simple UserValidator:
public class SimpleUserValidator<TUser, TKey> : IIdentityValidator<TUser> where TUser: class, IUser<TKey> where TKey : IEquatable<TKey> {
private readonly UserManager<TUser, TKey> _manager;
public SimpleUserValidator(UserManager<TUser, TKey> manager) {
_manager = manager;
}
public async Task<IdentityResult> ValidateAsync(TUser item) {
var errors = new List<string>();
if (string.IsNullOrWhiteSpace(item.UserName))
errors.Add("Username is required");
if (_manager != null) {
var otherAccount = await _manager.FindByNameAsync(item.UserName);
if (otherAccount != null && !otherAccount.Id.Equals(item.Id))
errors.Add("Select a different username. An account has already been created with this username.");
}
return errors.Any()
? IdentityResult.Failed(errors.ToArray())
: IdentityResult.Success;
}
}
I set this by calling:
manager.UserValidator = new SimpleUserValidator<ApplicationUser, int>(manager);
within the ApplicationUserManager.Create()
method.
The problem is, this doesn't change the behavior. I still get the default The Email field is not a valid e-mail address
message. Is this not the correct place to set that validation?
I had a similar issue to this question and the answer here is not quite right so I am adding mine here to share.
The issue was caused by setting the
UserValidator
inside the Create function. Since I was newing an instance of theApplicationUserManager
the default validator was being used. Moving the application validation setting to the constructor solved the problem. The Create function should only have the option specific settings I think.Alternatively you could remove all instances of
new ApplicationUserManager
, and call Create instead. But that is dificult to enforce on others using your code without making the constructor privateMaking the constructor private would make seeding the user table difficult because the
IOwinContext
is not available in the seeding function. Also you would not be able to unit test yourApplicationUserManager
by passing a mocked store during construction.I found it. And it should have been obvious.
The
UserValidator
is not the only thing you have to change for validation from a new template. You also must change all the relevant view models. Go figure.