UserManager.FindByEmailAsync возвращает ноль, но пользователь существует в базе данных - PullRequest
0 голосов
/ 14 января 2019

UserManager.FindByEmailAsync возвращает ноль, но пользователь существует в базе данных

Код ниже объясняет странную проблему:

var email = info.Principal.FindFirstValue(ClaimTypes.Email);
var test = new Data.ApplicationDbContext().Users.First(x => x.NormalizedEmail == email);
var usermail = await _userManager.FindByEmailAsync(email);

Console.WriteLine(test == null);      //false
Console.WriteLine(usermail == null);  //true

EDIT:

также через сам _userManager, желаемый пользователь получается

var test = _userManager.Users.FirstOrDefault(x => x.NormalizedEmail == email);
var usermail = await _userManager.FindByEmailAsync(email);

Console.WriteLine(test == null);      //false
Console.WriteLine(usermail == null);  //true

Следует отметить, что пользователь был создан не "обычным" способом, а с помощью Data-Seed (в OnModelCreating):

protected override void OnModelCreating(ModelBuilder builder)
{
    var users = new (string email, string name)[] {
        ("xyz@gmail.com", "admin")
    };

    var appUsers = users.Select(x => new ApplicationUser
    {
        Email = x.email,
        NormalizedEmail = x.email,
        NormalizedUserName = x.email,
        UserName = x.email,
        EmailConfirmed = true,
        Id = Guid.NewGuid().ToString(),
        SecurityStamp = Guid.NewGuid().ToString()
    }).ToArray();

    var role = new IdentityRole("Admins") { Id = Guid.NewGuid().ToString() };
    var roleToUser = appUsers.Select(x => new IdentityUserRole<string> { RoleId = role.Id, UserId = x.Id });

    builder.Entity<ApplicationUser>().HasData(appUsers);
    builder.Entity<IdentityRole>().HasData(role);
    builder.Entity<IdentityUserRole<string>>().HasData(roleToUser);

    base.OnModelCreating(builder);
}

Ответы [ 2 ]

0 голосов
/ 15 января 2019

Как вы можете видеть в ссылках на исходные коды в комментариях к вашему ОП FindByEmailAsync выполняет NormalizeKey , прежде чем он фактически начнет поиск пользователя.

email = NormalizeKey(email);

Это NormalizeKey(email) выполняется UpperInvariantLookupNormalizer , который будет выполнять следующую строковую операцию с вашим письмом

return key.Normalize().ToUpperInvariant();

Теперь часть вашего кода, которая вызывает «странное» поведение, - это отсутствующий вызов нормализации в вашем коде при создании пользователя:

var appUsers = users.Select(x => new ApplicationUser
{
    Email = x.email,
    NormalizedEmail = x.email,
    NormalizedUserName = x.email,
    UserName = x.email,
    EmailConfirmed = true,
    Id = Guid.NewGuid().ToString(),
    SecurityStamp = Guid.NewGuid().ToString()
}).ToArray();

Ненормализация электронного письма по-прежнему делает его обнаруживаемым через таблицу пользователей, поскольку это просто сравнивает NormalizedEmail (который вы не нормализовали при создании пользователя) с ненормализованным электронным письмом, которое вы передаете в качестве аргумента:

_userManager.Users.FirstOrDefault(x => x.NormalizedEmail == email);

... однако userManager.FindByEmailAsync нормализует сначала, а затем выполняет поиск ...

_userManager.FindByEmailAsync(email);

... и, следовательно, не найти пользователя.

Измените свой код на следующий:

// inject via using Microsoft.AspNetCore.Identity
protected ILookupNormalizer normalizer;

var appUsers = users.Select(x => new ApplicationUser
{
    Email = x.email,
    NormalizedEmail = normalizer.Normalize(x.email),
    NormalizedUserName = normalizer.Normalize(x.email),
    UserName = x.email,
    EmailConfirmed = true,
    Id = Guid.NewGuid().ToString(),
    SecurityStamp = Guid.NewGuid().ToString()
}).ToArray();
0 голосов
/ 15 января 2019

Для NormalizedEmail и NormalizedUserName это должна быть заглавная буква.

Попробуйте

var appUsers = users.Select(x => new ApplicationUser
{
    Email = x.email,
    NormalizedEmail = x.email.ToUpper(),
    NormalizedUserName = x.email.ToUpper(),
    UserName = x.email,
    EmailConfirmed = true,
    Id = Guid.NewGuid().ToString(),
    SecurityStamp = Guid.NewGuid().ToString()
}).ToArray();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...