title: aspnetcore username validations - User name '' is invalid, can only contain letters or digits
body: <p>I am trying to implement aspnetcore identity without entity framework and using direct connection to SQL Server and I created identityuser, userstore and usertable so far. I am trying to register a new user using the default Register View and using default Accounts controller's Register method which calls _usermanager.CreateAsync and it always throws error what ever the username is as 
  <strong>User name '' is invalid, can only contain letters or digits</strong> it says <strong>user name ''</strong> it is not saying the username that I entered but displays '', is that right?</p>
  
  <p>Configure services in Startup.cs looks as below</p>
  
  <pre><code>public void ConfigureServices(IServiceCollection services)
          {
              var roleStore = new RoleStore();
              var userPrincipalFactory = new ExampleUserPrincipalFactory();
              services.AddSingleton&lt;IUserStore&lt;IdentityUser&gt;, UserStore&lt;IdentityUser&gt;&gt;();
              services.AddSingleton&lt;IRoleStore&lt;IdentityRole&gt;&gt;(roleStore);
              services.AddSingleton&lt;IUserClaimsPrincipalFactory&lt;IdentityUser&gt;&gt;(userPrincipalFactory);
  
              services.AddIdentity&lt;IdentityUser, IdentityRole&gt;(options =&gt;
              {
                  options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@";
              }).AddDefaultTokenProviders();
  
              services.AddMvc();
  
              services.AddTransient&lt;IEmailSender, AuthMessageSender&gt;();
              services.AddTransient&lt;ISmsSender, AuthMessageSender&gt;();
          }
  </code></pre>
  
  <p>I have used AllowedUsernamesCharacters but it makes no difference. I few other old example for similar message advised to define the validator in the AccountsController Constructor but with latest aspnetcore the UserManager no longer has UserValidator property </p>
  
  <pre><code>UserManager.UserValidator = new UserValidator&lt;ApplicationUser&gt;(UserManager) { AllowOnlyAlphanumericUserNames = false };
  </code></pre>
  
  <p>I doubt My custom implemenation of IdentityUser, Usertore may have some errors, So I will give you those files here</p>
  
  <p><strong>IdentityUser</strong></p>
  
  <pre><code>public class IdentityUser
      {
          public IdentityUser()
          {
              Id = Guid.NewGuid().ToString();
          }
  
          public IdentityUser(string userName)
              : this()
          {
              UserName = userName;
          }
  
          public string Id { get; set; }    
          public string UserName { get; set; }
          public virtual string Email { get; set; }
          public virtual bool EmailConfirmed { get; set; }    
          public virtual string PasswordHash { get; set; }
          public virtual string SecurityStamp { get; set; }
          public virtual string PhoneNumber { get; set; }
          public virtual bool PhoneNumberConfirmed { get; set; }
          public virtual bool TwoFactorEnabled { get; set; }
          public virtual DateTime? LockoutEndDateUtc { get; set; }
          public virtual bool LockoutEnabled { get; set; }    
          public virtual int AccessFailedCount { get; set; }
      }
  </code></pre>
  
  <p><strong>UserStore</strong></p>
  
  <pre><code>    public class UserStore&lt;TUser&gt; : IUserStore&lt;TUser&gt;,
                                      IUserPasswordStore&lt;TUser&gt;,
                                      IUserLoginStore&lt;TUser&gt;,
                                      IUserPhoneNumberStore&lt;TUser&gt;,
                                      IUserTwoFactorStore&lt;TUser&gt;
              where TUser : IdentityUser
          {
              // Workaround create a new userTable instance when ever it is null
              private UserTable&lt;TUser&gt; userTable
              {
                  get
                  {
                      return new UserTable&lt;TUser&gt;(Database);
                  }
                  set
                  {
  
                  }
              }
              // Workaround create a new Database instance when ever it is null
              public MsSqlDatabase Database
              {
                  get
                  {
                      return new MsSqlDatabase();
                  }
                  private set
                  {
                  }
              }
  
              public IQueryable&lt;TUser&gt; Users
              {
                  get
                  {
                      throw new NotImplementedException();
                  }
              }
  
              public UserStore()
              {
                  new UserStore&lt;TUser&gt;(new MsSqlDatabase());
              }
  
              public UserStore(MsSqlDatabase database)
              {
                  Database = database;
                  userTable = new UserTable&lt;TUser&gt;(database);
                  //roleTable = new RoleTable(database);
                  //userRolesTable = new UserRolesTable(database);
                  //userClaimsTable = new UserClaimsTable(database);
                  //userLoginsTable = new UserLoginsTable(database);
              }
  
               public Task&lt;IdentityResult&gt; CreateAsync(TUser user, CancellationToken cancellationToken)
              {
                  if (user == null)
                  {
                      throw new ArgumentNullException("user");
                  }
  
                  userTable.Insert(user);
  
                  var a = IdentityResult.Success;
                  return new Task&lt;IdentityResult&gt;(() =&gt; a);
              }
  
              public async Task&lt;string&gt; GetUserIdAsync(TUser user, CancellationToken cancellationToken)
              {
                  List&lt;TUser&gt; result = userTable.GetUserById(user.Id) as List&lt;TUser&gt;;
                  if (result != null &amp;&amp; result.Count == 1)
                  {
                      return result[0].Id;
                  }
  
                  return null;
              }
  
              public async Task&lt;string&gt; GetUserNameAsync(TUser user, CancellationToken cancellationToken)
              {
                  if (string.IsNullOrEmpty(user.UserName))
                  {
                      throw new ArgumentException("Null or empty argument: userName");
                  }
  
                  List&lt;TUser&gt; result = userTable.GetUserByName(user.UserName) as List&lt;TUser&gt;;
  
                  // Should I throw if &gt; 1 user?
                  if (result != null &amp;&amp; result.Count == 1)
                  {
                      return result[0].UserName;
                  }
  
                  return null;
              }
  
              Task&lt;TUser&gt; IUserStore&lt;TUser&gt;.FindByNameAsync(string userName, CancellationToken cancellationToken)
              {
                  if (string.IsNullOrEmpty(userName))
                  {
                      throw new ArgumentException("Null or empty argument: userName");
                  }
  
                  List&lt;TUser&gt; result = userTable.GetUserByName(userName) as List&lt;TUser&gt;;
  
                  // Should I throw if &gt; 1 user?
                  if (result != null &amp;&amp; result.Count == 1)
                  {
                      return Task.FromResult&lt;TUser&gt;(result[0]);
                  }
  
                  return Task.FromResult&lt;TUser&gt;(null);
              }
  
              public Task SetPasswordHashAsync(TUser user, string passwordHash, CancellationToken cancellationToken)
              {
                  user.PasswordHash = passwordHash;
                  return Task.FromResult&lt;Object&gt;(null);
              }
  
              public void Dispose()
              {
                  if (Database != null)
                  {
                      Database.Dispose();
                      Database = null;
                  }
              }
  
              public Task AddLoginAsync(TUser user, UserLoginInfo login, CancellationToken cancellationToken)
              {
                  throw new NotImplementedException();
              }
  
              public Task&lt;IdentityResult&gt; DeleteAsync(TUser user, CancellationToken cancellationToken)
              {
                  throw new NotImplementedException();
              }
  
              public Task&lt;IList&lt;UserLoginInfo&gt;&gt; GetLoginsAsync(TUser user, CancellationToken cancellationToken)
              {
                  throw new NotImplementedException();
              }
  
              public Task&lt;string&gt; GetNormalizedUserNameAsync(TUser user, CancellationToken cancellationToken)
              {
                  throw new NotImplementedException();
              }
  
              public Task&lt;string&gt; GetPasswordHashAsync(TUser user, CancellationToken cancellationToken)
              {
                  throw new NotImplementedException();
              }
  
              public Task&lt;string&gt; GetPhoneNumberAsync(TUser user, CancellationToken cancellationToken)
              {
                  throw new NotImplementedException();
              }
  
              public Task&lt;bool&gt; GetPhoneNumberConfirmedAsync(TUser user, CancellationToken cancellationToken)
              {
                  throw new NotImplementedException();
              }
  
              public Task&lt;bool&gt; GetTwoFactorEnabledAsync(TUser user, CancellationToken cancellationToken)
              {
                  throw new NotImplementedException();
              }
  
              public Task&lt;bool&gt; HasPasswordAsync(TUser user, CancellationToken cancellationToken)
              {
                  throw new NotImplementedException();
              }
  
              public Task RemoveLoginAsync(TUser user, string loginProvider, string providerKey, CancellationToken cancellationToken)
              {
                  throw new NotImplementedException();
              }
  
              public Task SetNormalizedUserNameAsync(TUser user, string normalizedName, CancellationToken cancellationToken)
              {
                  throw new NotImplementedException();
              }
  
              public Task SetPhoneNumberAsync(TUser user, string phoneNumber, CancellationToken cancellationToken)
              {
                  throw new NotImplementedException();
              }
  
              public Task SetPhoneNumberConfirmedAsync(TUser user, bool confirmed, CancellationToken cancellationToken)
              {
                  throw new NotImplementedException();
              }
  
              public Task SetTwoFactorEnabledAsync(TUser user, bool enabled, CancellationToken cancellationToken)
              {
                  throw new NotImplementedException();
              }
  
              public Task SetUserNameAsync(TUser user, string userName, CancellationToken cancellationToken)
              {
                  throw new NotImplementedException();
              }
  
              public Task&lt;IdentityResult&gt; UpdateAsync(TUser user, CancellationToken cancellationToken)
              {
                  throw new NotImplementedException();
              }
  
              Task&lt;TUser&gt; IUserStore&lt;TUser&gt;.FindByIdAsync(string userId, CancellationToken cancellationToken)
              {
                  throw new NotImplementedException();
              }
  
              Task&lt;TUser&gt; IUserLoginStore&lt;TUser&gt;.FindByLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken)
              {
                  throw new NotImplementedException();
              }
          }
  
  **UserTable**
  
  public class UserTable&lt;TUser&gt; where TUser:IdentityUser
      {
          private MsSqlDatabase _database;
  
          public UserTable(MsSqlDatabase database)
          {
              _database = database;
          }
  
          public string GetUserName(string userId)
          {
              string commandText = "Select Name from Users where Id = @id";
              Dictionary&lt;string, object&gt; parameters = new Dictionary&lt;string, object&gt;() { { "@id", userId } };
  
              return _database.GetStrValue(commandText, parameters);
          }
  
          public string GetUserId(string userName)
          {
              string commandText = "Select Id from Users where UserName = @name";
              Dictionary&lt;string, object&gt; parameters = new Dictionary&lt;string, object&gt;() { { "@name", userName } };
  
              return _database.GetStrValue(commandText, parameters);
          }
  
          public TUser GetUserById(string userId)
          {
              TUser user = null;
              string commandText = "Select * from Users where Id = @id";
              Dictionary&lt;string, object&gt; parameters = new Dictionary&lt;string, object&gt;() { { "@id", userId } };
  
              var rows = _database.Query(commandText, parameters);
              if (rows != null &amp;&amp; rows.Count == 1)
              {
                  var row = rows[0];
                  user = (TUser)Activator.CreateInstance(typeof(TUser));
                  user.Id = row["Id"];
                  user.UserName = row["UserName"];
                  user.PasswordHash = string.IsNullOrEmpty(row["PasswordHash"]) ? null : row["PasswordHash"];
                  user.SecurityStamp = string.IsNullOrEmpty(row["SecurityStamp"]) ? null : row["SecurityStamp"];
                  user.Email = string.IsNullOrEmpty(row["Email"]) ? null : row["Email"];
                  user.EmailConfirmed = row["EmailConfirmed"] == "1" ? true : false;
                  user.PhoneNumber = string.IsNullOrEmpty(row["PhoneNumber"]) ? null : row["PhoneNumber"];
                  user.PhoneNumberConfirmed = row["PhoneNumberConfirmed"] == "1" ? true : false;
                  user.LockoutEnabled = row["LockoutEnabled"] == "1" ? true : false;
                  user.LockoutEndDateUtc = string.IsNullOrEmpty(row["LockoutEndDateUtc"]) ? DateTime.Now : DateTime.Parse(row["LockoutEndDateUtc"]);
                  user.AccessFailedCount = string.IsNullOrEmpty(row["AccessFailedCount"]) ? 0 : int.Parse(row["AccessFailedCount"]);
              }
  
              return user;
          }
  
          public List&lt;TUser&gt; GetUserByName(string userName)
          {
              List&lt;TUser&gt; users = new List&lt;TUser&gt;();
              string commandText = "Select * from Users where UserName = @name";
              Dictionary&lt;string, object&gt; parameters = new Dictionary&lt;string, object&gt;() { { "@name", userName } };
  
              var rows = _database.Query(commandText, parameters);
              foreach (var row in rows)
              {
                  TUser user = (TUser)Activator.CreateInstance(typeof(TUser));
                  user.Id = row["Id"];
                  user.UserName = row["UserName"];
                  user.PasswordHash = string.IsNullOrEmpty(row["PasswordHash"]) ? null : row["PasswordHash"];
                  user.SecurityStamp = string.IsNullOrEmpty(row["SecurityStamp"]) ? null : row["SecurityStamp"];
                  user.Email = string.IsNullOrEmpty(row["Email"]) ? null : row["Email"];
                  user.EmailConfirmed = row["EmailConfirmed"] == "1" ? true : false;
                  user.PhoneNumber = string.IsNullOrEmpty(row["PhoneNumber"]) ? null : row["PhoneNumber"];
                  user.PhoneNumberConfirmed = row["PhoneNumberConfirmed"] == "1" ? true : false;
                  user.LockoutEnabled = row["LockoutEnabled"] == "1" ? true : false;
                  user.TwoFactorEnabled = row["TwoFactorEnabled"] == "1" ? true : false;
                  user.LockoutEndDateUtc = string.IsNullOrEmpty(row["LockoutEndDateUtc"]) ? DateTime.Now : DateTime.Parse(row["LockoutEndDateUtc"]);
                  user.AccessFailedCount = string.IsNullOrEmpty(row["AccessFailedCount"]) ? 0 : int.Parse(row["AccessFailedCount"]);
                  users.Add(user);
              }
  
              return users;
          }
  
          public List&lt;TUser&gt; GetUserByEmail(string email)
          {
              return null;
          }
  
          public string GetPasswordHash(string userId)
          {
              string commandText = "Select PasswordHash from Users where Id = @id";
              Dictionary&lt;string, object&gt; parameters = new Dictionary&lt;string, object&gt;();
              parameters.Add("@id", userId);
  
              var passHash = _database.GetStrValue(commandText, parameters);
              if (string.IsNullOrEmpty(passHash))
              {
                  return null;
              }
  
              return passHash;
          }
  
          public int SetPasswordHash(string userId, string passwordHash)
          {
              string commandText = "Update Users set PasswordHash = @pwdHash where Id = @id";
              Dictionary&lt;string, object&gt; parameters = new Dictionary&lt;string, object&gt;();
              parameters.Add("@pwdHash", passwordHash);
              parameters.Add("@id", userId);
  
              return _database.Execute(commandText, parameters);
          }
  
          public string GetSecurityStamp(string userId)
          {
              string commandText = "Select SecurityStamp from Users where Id = @id";
              Dictionary&lt;string, object&gt; parameters = new Dictionary&lt;string, object&gt;() { { "@id", userId } };
              var result = _database.GetStrValue(commandText, parameters);
  
              return result;
          }
  
          public int Insert(TUser user)
          {
              string commandText = @"Insert into Users (UserName, Id, PasswordHash, SecurityStamp,Email,EmailConfirmed,PhoneNumber,PhoneNumberConfirmed, AccessFailedCount,LockoutEnabled,LockoutEndDateUtc,TwoFactorEnabled)
                  values (@name, @id, @pwdHash, @SecStamp,@email,@emailconfirmed,@phonenumber,@phonenumberconfirmed,@accesscount,@lockoutenabled,@lockoutenddate,@twofactorenabled)";
              Dictionary&lt;string, object&gt; parameters = new Dictionary&lt;string, object&gt;();
              parameters.Add("@name", user.UserName);
              parameters.Add("@id", user.Id);
              parameters.Add("@pwdHash", user.PasswordHash);
              parameters.Add("@SecStamp", user.SecurityStamp);
              parameters.Add("@email", user.Email);
              parameters.Add("@emailconfirmed", user.EmailConfirmed);
              parameters.Add("@phonenumber", user.PhoneNumber);
              parameters.Add("@phonenumberconfirmed", user.PhoneNumberConfirmed);
              parameters.Add("@accesscount", user.AccessFailedCount);
              parameters.Add("@lockoutenabled", user.LockoutEnabled);
              parameters.Add("@lockoutenddate", user.LockoutEndDateUtc);
              parameters.Add("@twofactorenabled", user.TwoFactorEnabled);
  
              return _database.Execute(commandText, parameters);
          }
  
          private int Delete(string userId)
          {
              string commandText = "Delete from Users where Id = @userId";
              Dictionary&lt;string, object&gt; parameters = new Dictionary&lt;string, object&gt;();
              parameters.Add("@userId", userId);
  
              return _database.Execute(commandText, parameters);
          }
  
          public int Delete(TUser user)
          {
              return Delete(user.Id);
          }
  
          public int Update(TUser user)
          {
              string commandText = @"Update Users set UserName = @userName, PasswordHash = @pswHash, SecurityStamp = @secStamp, 
                  Email=@email, EmailConfirmed=@emailconfirmed, PhoneNumber=@phonenumber, PhoneNumberConfirmed=@phonenumberconfirmed,
                  AccessFailedCount=@accesscount, LockoutEnabled=@lockoutenabled, LockoutEndDateUtc=@lockoutenddate, TwoFactorEnabled=@twofactorenabled  
                  WHERE Id = @userId";
              Dictionary&lt;string, object&gt; parameters = new Dictionary&lt;string, object&gt;();
              parameters.Add("@userName", user.UserName);
              parameters.Add("@pswHash", user.PasswordHash);
              parameters.Add("@secStamp", user.SecurityStamp);
              parameters.Add("@userId", user.Id);
              parameters.Add("@email", user.Email);
              parameters.Add("@emailconfirmed", user.EmailConfirmed);
              parameters.Add("@phonenumber", user.PhoneNumber);
              parameters.Add("@phonenumberconfirmed", user.PhoneNumberConfirmed);
              parameters.Add("@accesscount", user.AccessFailedCount);
              parameters.Add("@lockoutenabled", user.LockoutEnabled);
              parameters.Add("@lockoutenddate", user.LockoutEndDateUtc);
              parameters.Add("@twofactorenabled", user.TwoFactorEnabled);
  
              return _database.Execute(commandText, parameters);
          }
      }
  </code></pre>
  
  <p><strong>MySqlDatabase</strong></p>
  
  <pre><code>public class MsSqlDatabase : IDisposable
      {
          private SqlConnection _connection;
  
          public MsSqlDatabase()
              : this("DefaultConnection")
          {
          }
  
          public MsSqlDatabase(string connectionStringName)
          {
              string connectionString = "Server=(localdb)\\mssqllocaldb;Database=SampleIdentity;Trusted_Connection=True;MultipleActiveResultSets=true";
              _connection = new SqlConnection(connectionString);
          }
  
          public int Execute(string commandText, Dictionary&lt;string, object&gt; parameters)
          {
              int result = 0;
  
              if (String.IsNullOrEmpty(commandText))
              {
                  throw new ArgumentException("Command text cannot be null or empty.");
              }
  
              try
              {
                  EnsureConnectionOpen();
                  var command = CreateCommand(commandText, parameters);
                  result = command.ExecuteNonQuery();
              }
              finally
              {
                  _connection.Close();
              }
  
              return result;
          }
  
          public object QueryValue(string commandText, Dictionary&lt;string, object&gt; parameters)
          {
              object result = null;
  
              if (String.IsNullOrEmpty(commandText))
              {
                  throw new ArgumentException("Command text cannot be null or empty.");
              }
  
              try
              {
                  EnsureConnectionOpen();
                  var command = CreateCommand(commandText, parameters);
                  result = command.ExecuteScalar();
              }
              finally
              {
                  EnsureConnectionClosed();
              }
  
              return result;
          }
  
          public List&lt;Dictionary&lt;string, string&gt;&gt; Query(string commandText, Dictionary&lt;string, object&gt; parameters)
          {
              List&lt;Dictionary&lt;string, string&gt;&gt; rows = null;
              if (String.IsNullOrEmpty(commandText))
              {
                  throw new ArgumentException("Command text cannot be null or empty.");
              }
  
              try
              {
                  EnsureConnectionOpen();
                  var command = CreateCommand(commandText, parameters);
                  using (DbDataReader reader = command.ExecuteReader())
                  {
                      rows = new List&lt;Dictionary&lt;string, string&gt;&gt;();
                      while (reader.Read())
                      {
                          var row = new Dictionary&lt;string, string&gt;();
                          for (var i = 0; i &lt; reader.FieldCount; i++)
                          {
                              var columnName = reader.GetName(i);
                              var columnValue = reader.IsDBNull(i) ? null : reader.GetString(i);
                              row.Add(columnName, columnValue);
                          }
                          rows.Add(row);
                      }
                  }
              }
              finally
              {
                  EnsureConnectionClosed();
              }
  
              return rows;
          }
  
          private void EnsureConnectionOpen()
          {
              var retries = 3;
              if (_connection.State == ConnectionState.Open)
              {
                  return;
              }
              else
              {
                  while (retries &gt;= 0 &amp;&amp; _connection.State != ConnectionState.Open)
                  {
                      _connection.Open();
                      retries--;
                      Task.Delay(30).Wait();
                  }
              }
          }
  
          public void EnsureConnectionClosed()
          {
              if (_connection.State == ConnectionState.Open)
              {
                  _connection.Close();
              }
          }
  
          private DbCommand CreateCommand(string commandText, Dictionary&lt;string, object&gt; parameters)
          {
              DbCommand command = _connection.CreateCommand();
              command.CommandText = commandText;
              AddParameters(command, parameters);
  
              return command;
          }
  
          private static void AddParameters(DbCommand command, Dictionary&lt;string, object&gt; parameters)
          {
              if (parameters == null)
              {
                  return;
              }
  
              foreach (var param in parameters)
              {
                  var parameter = command.CreateParameter();
                  parameter.ParameterName = param.Key;
                  parameter.Value = param.Value ?? DBNull.Value;
                  command.Parameters.Add(parameter);
              }
          }
  
          public string GetStrValue(string commandText, Dictionary&lt;string, object&gt; parameters)
          {
              string value = QueryValue(commandText, parameters) as string;
              return value;
          }
  
          public void Dispose()
          {
              if (_connection != null)
              {
                  _connection.Dispose();
                  _connection = null;
              }
          }
      }
  </code></pre>
  
  <p><strong>ExampleUserPrincipalFactory</strong></p>
  
  <pre><code> public class ExampleUserPrincipalFactory:IUserClaimsPrincipalFactory&lt;IdentityUser&gt;
  {
      public Task&lt;ClaimsPrincipal&gt; CreateAsync(IdentityUser user)
      {
          ClaimsIdentity identity = new ClaimsIdentity("Microsoft.AspNet.Identity.Application");
          identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, user.Id));
          identity.AddClaim(new Claim(ClaimTypes.Name, user.UserName));
          identity.AddClaim(new Claim(ClaimTypes.Email, user.Email));
  
          ClaimsPrincipal principal = new ClaimsPrincipal(identity);
  
          return Task.FromResult(principal);
      }
  }
  </code></pre>
  
  <p>If you like to see any other class definition please let me know.</p>