1

I want to implement custom logic for username validation. Created function ValidateEntity for username custom validation but if I provide unique username while creating user then ValidateEntity function is hit and If I provide duplicate username then this function is not hit.

IdentityModel.cs

    public class ApplicationUser : IdentityUser
        {
            public int AppId { get; set; }
            //other attributes
            public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
            {
                var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
                return userIdentity;
            }
        }
    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
        {
            public ApplicationDbContext()
                : base("DefaultConnection", throwIfV1Schema: false)
            {
            }

            public static ApplicationDbContext Create()
            {
                return new ApplicationDbContext();
            }

            protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
            {
                if ((entityEntry != null) && (entityEntry.State == EntityState.Added))
                {
                    var user = entityEntry.Entity as ApplicationUser;
                    //custom logic for username validation
                }
                return base.ValidateEntity(entityEntry, items);
            }
        }

In AccountController.cs

public async Task<ActionResult> Register(RegisterViewModel model)
        {
            if (ModelState.IsValid)
            {
                var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
                var result = await UserManager.CreateAsync(user, model.Password); //shouldn't it always goto ValidateEntity function?
                if (result.Succeeded)
                {
                    await SignInManager.SignInAsync(user, isPersistent:false, rememberBrowser:false);
                    return RedirectToAction("Index", "Home");
                }
                AddErrors(result);
            }
            return View(model);
        }

Update: I added public new string UserName { get; set; } and now I get error Name cannot be null or empty here is the screen shot of data.

enter image description here

Irfan Y
  • 1,242
  • 2
  • 21
  • 68
  • If you haven't already, it would be worth checking out the answers to [this question](https://stackoverflow.com/questions/29628850/microsoft-asp-net-identity-multiple-users-with-the-same-name) – RickL May 24 '18 at 10:31
  • Thanks, I already tried this solution, unfortunately it didn't worked. – Irfan Y May 24 '18 at 10:39
  • Did you ever find a solution to your answer? – JianYA Dec 05 '19 at 12:30

1 Answers1

0

It is not good practice for the username field not to be unique, unless you plan to cover that in your custom validator. However you should be able to override the username field in the ApplicationUser class:

public class ApplicationUser : IdentityUser
{
    public int AppId { get; set; }

    // Override username field
    public new string UserName { get; set; }

    //other attributes
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        return userIdentity;
    }
}

Additionally, if your database already exists, you must also then remember to remove the unique index UserNameIndex for everything to work.

Kyle
  • 1,013
  • 8
  • 16