繁体   English   中英

UserManager.FindByEmailAsync 返回 null,但该用户存在于数据库中

[英]UserManager.FindByEmailAsync returns null, but the user exists in the database

UserManager.FindByEmailAsync返回null ,但该用户存在于数据库中。

下面的代码解释了这个奇怪的问题:

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

编辑

同样通过_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);
}

正如您在我对您的 OP FindByEmailAsync所做的评论中的源代码链接中看到的那样,它在实际开始搜索用户之前执行了NormalizeKey

email = NormalizeKey(email);

NormalizeKey(email)UpperInvariantLookupNormalizer完成,它将对您的电子邮件执行以下字符串操作

return key.Normalize().ToUpperInvariant();

现在,导致“奇怪”行为的代码部分是在创建用户时缺少对代码中的 normalize 调用:

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();

不规范化电子邮件仍然可以通过 users 表发现它,因为这只是将NormalizedEmail (您在创建用户时没有规范化)与您作为参数传递的非规范化电子邮件进行比较:

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

...但是, userManager.FindByEmailAsync将首先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();

对于NormalizedEmailNormalizedUserName ,它应该是大写字母。

尝试

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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM