3

Asp.net Identity doesn't allow same username for two or more users even if the primary key in AspNetUsers table is the Id, so i tried to ovveride the UserValidator of the UserManager but it stills give me errors that i can't give two users the same username , here is the custom validator:

public class CustomUserValidator<TUser> : IIdentityValidator<TUser>
 where TUser : ApplicationUser, Microsoft.AspNet.Identity.IUser
{
    private readonly UserManager<TUser> _manager;

    public CustomUserValidator()
    {
    }

    public CustomUserValidator(UserManager<TUser> manager)
    {
        _manager = manager;
    }

    public async Task<IdentityResult> ValidateAsync(TUser item)
    {
        var errors = new List<string>();


        if (_manager != null)
        {
            var otherAccount = await _manager.FindByNameAsync(item.UserName);
            if (otherAccount != null && otherAccount.CodeClient == item.CodeClient)
                errors.Add("Utilisateur existant.");
        }

        return errors.Any()
            ? IdentityResult.Failed(errors.ToArray())
            : IdentityResult.Success;
    }
}

and in the constructor of my controller i change the uservalidator property like this :

public UsersRootController(UserManager<ApplicationUser> userManager, RoleManager<IdentityRole> roleManager)
    {
        UserManager = userManager;
        RoleManager = RoleManager;
        UserManager.UserValidator = new CustomUserValidator<ApplicationUser>(userManager);
    }

When i try to call the createasync method :

  var user = new ApplicationUser() { UserName = model.UserName, Email = model.Email, Nom = model.Nom, Prenom = model.Prenom, IsEnabled = model.IsEnabled, CodeClient = model.Client };
   resultUser = await UserManager.CreateAsync(user, model.Password);

It uses my custom validator but returns always false .

Is there any way to fix that ?

1 Answer 1

1

I had a same problem but with Role.

The problem is Microsoft strategy against validation! He check uniqueness through IIdentityValidator and also inside of IdentityDbContext. why two times? I don't know! To solve this problem take a look into the source code (here : https://aspnetidentity.codeplex.com/SourceControl/latest#src/Microsoft.AspNet.Identity.EntityFramework/IdentityDbContext.cs) and simply override it like something I did for Role :

public class ApplicationIdentityDbContext : IdentityDbContext<...>
{
    protected override System.Data.Entity.Validation.DbEntityValidationResult ValidateEntity(System.Data.Entity.Infrastructure.DbEntityEntry entityEntry, IDictionary<object, object> items)
    {
        if (entityEntry != null && entityEntry.State == EntityState.Added)
        {
            //NOTE : change the following codes to support your needs!
            var role = entityEntry.Entity as ApplicationRole;
            if (role != null)
            {
                var errors = new List<DbValidationError>();
                return new DbEntityValidationResult(entityEntry, errors);
            }
        }

        return base.ValidateEntity(entityEntry, items);

    }
}

After that you should force your Store, to use this new context.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.