locked
Register with unique email OR unique username in ASP.NET Core MVC RRS feed

  • Question

  • User-1741097413 posted

    I am working with a system that should allow users to register by a unique username, or unique email. Register by both is possible as well.
    I am using the default identity pages with some modifications, here is a sample of the register code:

        public class InputModel
        {
            //[Required] //Validated in server side based on role
            [EmailAddress]
            [Display(Name = "Email")]
            public string Email { get; set; }
    
            //[Required] //Validated in server side based on role
            [Display(Name = "Username")]
            public string UserName { get; set; }
    
            [Required]
            [Display(Name = "Name")]
            public string Name { get; set; }
        }
    
        public async Task<IActionResult> OnPostAsync(string returnUrl = null)
        {
            string username = Input.UserName ?? Input.Email;
    
            if (ModelState.IsValid)
            {
                var user = new ApplicationUser
                {
                    UserName = username,
                    Email = Input.Email,
                    Name = Input.Name,
                };
            }
        }

    Basically, if the user entered a username, Username column will be Input.UserName. if no username (only email), the Username = Input.Email, because obviously it cannot be empty. Now both username and email are equal as the default.

    examples:
    Username: a@a , Email: a@a , >> no username
    Username: xyz , Email: null , >> no email
    Username: abc , Email: a@b , >> user entered both username and email

    For now, username is always unique and always required (required by identity not the user), but not the case for the email, it can be null as expected but not unique, I added this line in the startup.cs for the uniqueness:

                services.AddIdentity<IdentityUser, IdentityRole>(options => {
                options.User.RequireUniqueEmail = true;
            })

    but now it cannot be null, it give this validation error:

    Email '' is invalid.

    Saturday, November 28, 2020 8:44 PM

All replies

  • User-474980206 posted

    It’s a database limitation. If the key is unique, there can only be one null row. You will need add your own validation. 

    Saturday, November 28, 2020 8:48 PM
  • User-1741097413 posted

    It’s a database limitation. If the key is unique, there can only be one null row. You will need add your own validation. 

    can you be more specific please

    Saturday, November 28, 2020 9:08 PM
  • User711641945 posted

    Hi rosaud,

    You could custom validation like below:

        public class EmailValidator<TUser> : IUserValidator<TUser>
           where TUser : IdentityUser
        {
            public Task<IdentityResult> ValidateAsync(UserManager<TUser> manager,
                                                      TUser user)
            {
                if(user.Email==null)
                {
                    return Task.FromResult(IdentityResult.Success);
                }
                else
                {
                    var userExist = manager.FindByEmailAsync(user.Email);
                    if (userExist.Result==null)
                    {
                        return Task.FromResult(IdentityResult.Success);
                    }
                }
    
                return Task.FromResult(
                         IdentityResult.Failed(new IdentityError
                         {
                             Code = "400",
                             Description = "Email is not unique."
                         }));
            }
        }

    Startup.cs:

      services.AddIdentity<ApplicationUser, IdentityRole>()
            .AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultUI()
            .AddUserValidator<EmailValidator<ApplicationUser>>(); 

    Best Regards,

    Rena

    Monday, November 30, 2020 6:40 AM