简体   繁体   English

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

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

UserManager.FindByEmailAsync returns null , but the user exists in the database. UserManager.FindByEmailAsync返回null ,但该用户存在于数据库中。

The code below explain the strange problem:下面的代码解释了这个奇怪的问题:

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编辑

Also via _userManager itself, the desired user is obtained:同样通过_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

It should be noted that the user was not created in a "conventional" manner, but by Data-Seed (in OnModelCreating ):应该注意的是,用户不是以“传统”方式创建的,而是由 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);
}

As you can see in the source-code links in the comments I made to your OP FindByEmailAsync performs a NormalizeKey before it actually starts searching for the user.正如您在我对您的 OP FindByEmailAsync所做的评论中的源代码链接中看到的那样,它在实际开始搜索用户之前执行了NormalizeKey

email = NormalizeKey(email);

This NormalizeKey(email) is done by the UpperInvariantLookupNormalizer that will do the following string operation on your emailNormalizeKey(email)UpperInvariantLookupNormalizer完成,它将对您的电子邮件执行以下字符串操作

return key.Normalize().ToUpperInvariant();

Now the part of your code that is causing the "strange" behaviour is the missing call to normalize in your code when creating the user:现在,导致“奇怪”行为的代码部分是在创建用户时缺少对代码中的 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();

Not normalizing the email will still make it discoverable via the users table as this simply compares the NormalizedEmail (which you did not normalize when you created the user) with the not-normalized email you pass as argument:不规范化电子邮件仍然可以通过 users 表发现它,因为这只是将NormalizedEmail (您在创建用户时没有规范化)与您作为参数传递的非规范化电子邮件进行比较:

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

...however, userManager.FindByEmailAsync will normalize it first and afterwards do the search... ...但是, userManager.FindByEmailAsync将首先userManager.FindByEmailAsync进行规范化然后再进行搜索...

_userManager.FindByEmailAsync(email);

...and therefore not find the user. ...因此找不到用户。

Change your code to the following:将您的代码更改为以下内容:

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

For NormalizedEmail and NormalizedUserName , it should be uppercase letter.对于NormalizedEmailNormalizedUserName ,它应该是大写字母。

Try尝试

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.

相关问题 _userManager.GetUserAsync(User) 返回 null - _userManager.GetUserAsync(User) returns null ASP.NET Core身份UserManager使用FindByEmailAsync查找不存在的用户 - ASP.NET Core Identity UserManager Finds non-existant user with FindByEmailAsync 尽管使用UserManager扩展方法,FindAsync仍返回null - FindAsync returns null despite UserManager extension method JWT 身份验证 - UserManager.GetUserAsync 返回 null - JWT Authentication - UserManager.GetUserAsync returns null 身份 userManager.FindByNameAsync() 返回 null 值 - Identity userManager.FindByNameAsync() returns null value 用户存在于aspnet_membership表中,但getUser仍返回null - User exists in aspnet_membership table but getUser still returns null 密码重置后,UserManager.FindAsync返回null - UserManager.FindAsync returns null after password reset 单元测试:用户管理器<applicationuser>模拟设置 FindByIdAsync 返回 NULL</applicationuser> - UnitTests: UserManager<ApplicationUser> Mock Setup FindByIdAsync Returns NULL UserManager.GetUserAsync(User)是否可以在具有Authorize属性的类中返回null? - Can UserManager.GetUserAsync(User) return null in a class with Authorize attribute? UserManager.AddToRole将空用户ID传递给FindByIdAsync - UserManager.AddToRole passes null user id to FindByIdAsync
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM