34

I'm trying to create a custom implementation of IUserLoginStore for MongoDB and I noticed when using

UserManager<ApplicationUser>

with the method

 var userResult = await _userManager.CreateAsync(user);

it goes through the implementation of

GetUserNameAsync
FindByNameAsync
SetNormalizedUserNameAsync
GetUserIdAsync

I would like to clarify two questions:

  • what's the purpose of having a NormalizedUsername and a UserName? the only difference that I could notice id that the normalizedUserName is in uppercase.

  • I'm using my Implementation only to store users from an external login(Google plus), is there a way that I can omit username and NormilizedUserName since basically, I'm using the email in these three fields, I'm feeling that I'm duplicating data and it doesn't make any sense to me.

any recommendations?

Tseng
  • 61,549
  • 15
  • 193
  • 205
pedrommuller
  • 15,741
  • 10
  • 76
  • 126

3 Answers3

29

1) Normalization stops people registering user names which only differ in letter casing.

2) No - those fields are part of the basic data model.

blowdart
  • 55,577
  • 12
  • 114
  • 149
  • 3
    Nope. That's entirely in your hands I'm afraid. – blowdart Sep 23 '16 at 15:36
  • 8
    Yes, normalization is done in order to stop people registering user names which only differ in letter casing. But what the OP is asking, i.e. "what's the purpose of having a NormalizedUsername" in the database, is that it increases performance compared with doing this at runtime in the SQL query. More information here: https://github.com/aspnet/Identity/issues/351 – Svein Fidjestøl Jan 26 '17 at 10:40
  • FYI, at least for my case using dot net core 3.1 with Asp.Net Core Identity and ID4, the NormalizedUserName must be in uppercases. Otherwise, the user login would fail. – Nathan W Feb 08 '21 at 23:58
21
  1. Yes, you can (if you really want):
    1. FindByNameAsync should search by u.Name case-insensitive (do you trust your DB settings?)
    2. GetNormalizedUserNameAsync should return user.Name.ToUpperCase()
    3. SetNormalizedUserNameAsync should do nothing

Please note that 2.1 can skip any index on name column in DB and hurt performance of your app (check your DB, again). Or cause 'client-side' execution (and again, dramatically hurt performance). Depending of your implementation.

I use such "minimized" User class only in internal enterprise systems which uses only specific OAuth provider and accepting users only from specified domain (Google Apps). This systems does not perform any search by user name and I safely throw NotImplementedException in many methods.

Dmitry
  • 16,110
  • 4
  • 61
  • 73
  • yeah, I was thinking about different interface similar to IUserLoginStore with less code, I like those implementations to be more granular and not ending up with not implemented methods, thanks for the answer! – pedrommuller Sep 27 '16 at 16:07
  • 2
    Some comments: 1) In most cases, I would recommend using `ToUpperInvariant`. 2) I think `user.Name` should be `user.UserName`. 3) In many cases I would also replace the related email normalization variations (e.g., `FindByEmail`) 4) If you use this technique, consider configuring the normalized columns as sparse columns. 5) On a tangential note, I had to do the same thing prior to .Net Core. The default behavior was to normalize by embedding `Upper` into the generated SQL, bypassing existing indexes.. – Brian Jun 19 '19 at 16:15
  • What if you just tailored the get/find operations to force a lookup by email anyway and the set methods to only set the email? The interface only needs to implement the method signatures, what you put inside them is up to you. I haven’t tested this, but have asked the same essential question. In any real world scenario, I would test the case on email and username anyway. How substantial is the performance gain to make the fields redundant? – John Ernest Mar 24 '20 at 03:08
-9

The Normalized Name ensures that symbols used by URL Encoding such as &, ? and Quotes aren't included so that it can be used as a QueryString() or in a URL, and it will survive Encoding unscathed.

Emails don't include those characters which are probably being checked/disallowed by Validation so in this particular case there is not difference between Name and Normalized name.

David Elyk
  • 49
  • 2