11

I have changed my Register Action Method to accept user Name instead of Email.

if (ModelState.IsValid)
{
    var user = new ApplicationUser 
    {
        UserName = model.Name,
        Email = model.Email,
    };

But when I Enter Name in TextBox like Joe Smith It give me an error that is Invalid UserName. It is not allowing user Name to Accept White space. My Question is how can I modify the builtin User Name to allow space and special characters. I am using ASP.NET Core.

Thanks in Advance.

MethodMan
  • 18,625
  • 6
  • 34
  • 52
Babar
  • 109
  • 1
  • 2
  • 7

9 Answers9

11

You can set user validation rules configuring identity with options in your Startup.cs.

services.AddIdentity<ApplicationUser, IdentityRole>(options => {
    options.User.AllowedUserNameCharacters = "allowed characters here";
    options.User.RequireUniqueEmail = true/false;
});

Related resources:

Configure Identity

dropoutcoder
  • 2,627
  • 2
  • 14
  • 32
11

So cloudikka's answer had it right. I'll just add explicitly (cloudikka's link explained it as well) that you need to list ALL the characters you want to allow (not just the whitespace or special characters), like this:

services.AddIdentity<ApplicationUser, IdentityRole>(options => {
    options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+/ ";
});

and NOT this options.User.AllowedUserNameCharacters = " "; which means 'only whitespace characters allowed'. (I reckon this was Babar's problem.)

bsigma1
  • 260
  • 4
  • 10
  • this should be marked as answer. it works for me. the AllowedUserNameCharacters should be set with ALL characters we want to allow. – James Rao Aug 20 '21 at 11:10
5
services.AddIdentity<ApplicationUser, IdentityRole>(options => { options.User.AllowedUserNameCharacters = String.Empty; options.User.RequireUniqueEmail = true; })
            .AddEntityFrameworkStores<ApplicationDbContext>().AddDefaultTokenProviders();
IQtheMC
  • 221
  • 3
  • 12
  • 2
    I found that I needed to support a wide variety of characters as they already existed in customer installs so this worked best for me - It disables the checking on user names. – Mog0 Jun 01 '18 at 15:29
5

The proposed solution can be tricky if you have an exhaustive list of special characters to whitelist.

If you want to blacklist instead, disable the whitelist in startup.cs:

 services.AddIdentity<User, Role>(
                options =>
                {                        
                    options.User.AllowedUserNameCharacters = string.Empty;
                })

Then create your custom user validator

 public class UsernameValidator<TUser> : IUserValidator<TUser>
where TUser : User
{
    public Task<IdentityResult> ValidateAsync(UserManager<TUser> manager, TUser user)
    {                
        if (user.UserName.Any(x=>x ==':' || x == ';' || x == ' ' || x == ','))
        {
            return Task.FromResult(IdentityResult.Failed(new IdentityError
            {
                Code = "InvalidCharactersUsername",
                Description = "Username can not contain ':', ';', ' ' or ','"
            }));
        }
        return Task.FromResult(IdentityResult.Success);
    }        
}

Then add it to startup.cs:

 services.AddIdentity<User, Role>(
                options =>
                {
                    options.Password = new PasswordOptions
                    {
                        RequiredLength = 8,
                        RequireUppercase = true,
                        RequireNonAlphanumeric = true,
                        RequireDigit = true,
                        RequireLowercase = true
                    };
                    options.User.AllowedUserNameCharacters = string.Empty;
                }).AddUserValidator<UsernameValidator<User>>()
1

This is one of the problems caused by the en-US default mindset of most application developers..

I generated a small class that does this for me like so...

options.User.AllowedUserNameCharacters =Utilities.GetAllWritableCharacters(encoding: System.Text.Encoding.UTF8);

the helper class contains the GetAllWritableCharacters method like so

public class Utilities
{
    public static string GetAllWritableCharacters(Encoding encoding)
    {
        encoding = Encoding.GetEncoding(encoding.WebName, new EncoderExceptionFallback(), new DecoderExceptionFallback());
        var sb= new StringBuilder();
         
        char[] chars = new char[1];
        byte[] bytes = new byte[16];

           
        for (int i = 20; i <=  char.MaxValue; i++)
        {
            chars[0] = (char)i;
            try
            {
                int count = encoding.GetBytes(chars, 0, 1, bytes, 0);

                if (count != 0)
                {
                    sb.Append(chars[0]);
                }
            }
            catch 
            {
                break;
            }
        }
        return sb.ToString();
    }
}

now you can accept all meaningful characters from a character set including spaces and "exotic" letters

Walter Verhoeven
  • 3,867
  • 27
  • 36
1
services.AddIdentity<AppUser, AppRole>(opts =>
        {

            opts.User.RequireUniqueEmail = true;
            opts.User.AllowedUserNameCharacters =
            "abcçdefgğhijklmnoöpqrsştuüvwxyzABCÇDEFGĞHIİJKLMNOÖPQRSŞTUÜVWXYZ0123456789-._";
            opts.Password.RequiredLength = 4;
            opts.Password.RequireNonAlphanumeric = false;
            opts.Password.RequireLowercase = false;
            opts.Password.RequireUppercase = false;
            opts.Password.RequireDigit = false;
        }).AddPasswordValidator<CustomPasswordValidator>().AddEntityFrameworkStores<AppIdentityDbContext>();

You can basically enter any character you want between two quotes. options.User.AllowedUserNameCharacters = " ";

0

Yes, Username is same as Email. Email allows special characters such as "+" and "/". So, special characters in Username is expected.

Special characters in Email Address discussed here: What characters are allowed in an email address?

Joel
  • 1
  • 1
-2

As mentioned by @Jaffal the UserName should not allow special characters or white spaces. It should be considered as a unique user identifier (a.k.a. nickname or email). To get nicely displayed user name you might want to introduce a new property.

E.g. add a new property called Name or in some other implementation may be two fields GivenName and FamilyName. And ask user to fill in her name to these fields.

To extend the database with the extra field(s) your migration can be:

public partial class ApplicationUserNamePropertyAdded : Migration
{
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AddColumn<string>(
            name: "Name",
            table: "AspNetUsers",
            nullable: true);
    }

    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropColumn(
            name: "Name",
            table: "AspNetUsers");
    }
}

In your code when you Register a new user using ASP.NET Identity classes you will have a code line like:

var user = new ApplicationUser { UserName = model.Email, Email = model.Email, Name = model.Name };

Basically, the user's UserName will always be the same as Email and another Name property will be used for displaying purposes.

dmytrops
  • 496
  • 7
  • 11
-3

UserName should not allow special characters or white spaces, I don't think that there is any website will allow you to do that, you can use FirstName and Last name to get an info like "Joe Smith".

cs95
  • 379,657
  • 97
  • 704
  • 746
AJ -
  • 621
  • 5
  • 9
  • 1
    I just want to store full Name First Name + Last Name in table and It has to a space between them. – Babar Dec 27 '17 at 08:54
  • Then as I told you keep username as is and use a new property FullName in ApplicationUser class – AJ - Dec 27 '17 at 08:57
  • Ok How can I allow duplicate username? Is this possible? – Babar Dec 27 '17 at 09:03
  • @Jaffal: Whitesoace is bad practice because username is handle and it is used in the address bar and Joe%20Smith is ugly. Special characters can make web page behave strange(? querystring, # fragment). That is why we are not using special characters in general. Also special characters are not exactly human friendly and readable. Except _ or -. – dropoutcoder Dec 27 '17 at 09:22
  • @Babar It is not good idea to have duplicity in usernames. Username is handle and have to be unique. – dropoutcoder Dec 27 '17 at 09:23
  • @cloudikka that's why I told Babar to keep username as is and use new property call it FullName for the purpose he wants and username will stay as is unique doesn't accept special characters or whitespaces Babar just create new property inside ApplicationUser – AJ - Dec 27 '17 at 09:27
  • @Jaffal: I just extend your comment! I didnt meant to disagree with you. – dropoutcoder Dec 27 '17 at 09:29