ASP.NET Core MVC _userManager.FindByEmailAsync(Input.Email) returns null despite existing user with the same email

127 Views Asked by At

I am encountering an issue while implementing a password reset feature in my ASP.NET Core MVC application. After sending the reset token to the user's email and clicking the link to set a new password, I find that the line

var user = await _userManager.FindByEmailAsync(Input.Email);

in my ResetPassword class always returns null, even though I have confirmed that a user with the same email exists. I have verified that there is indeed a user with the specified email address by first retrieving all the users and then using a lambda expression to check the collection:

var allUsers = _userManager.Users.ToListAsync();
var user = allUsers.FirstOrDefault(x => x.Email == Input.Email);

but this also returns null for user. The next thing I tried doing is using a foreach loop to iterate through the list of users to manually verify if it's a problem with different datatypes. And I found that the string.Compare() or string1 == string2 expression always returned false when I compared both emails. Even when both were identical in case, or even if I normalized the input email beforehand.

foreach (var us1 in allUsers)
{
    if (us1.Email.ToLower() == Input.Email.ToLower())
    {
        // Breakpoint ... Found ... I never get to this breakpoint 
    }
}

Strangely, I use _userManager in the Register class, and _userManager.FindByEmailAsync(Input.Email) returns the expected user.

  1. I have checked that the email address is valid and exist in the database

  2. I'm using ASP.NET Core MVC with Identity.

  3. Other operations with _userManager.FindByEmail seem to be working correctly in different parts of the application. I used in in Register.cs to implement validation that prevents two userNames from being registered with same email address.

  4. I have also verified that UserManager is being injected into the constructor of my ResetPassword class. I have seen other similar answers here but the suggestions didn't help.

  5. (Edit), If I use the username on userManager like so

var user = await _userManager.FindByNameAsync("username");

The above will return the correct user provided the username exist. But this is not ideal because I can't get the userName when resetting password.

Any insights or suggestions on what might be causing this issue would be greatly appreciated. Thank you!

2

There are 2 best solutions below

0
Ken Janka On BEST ANSWER

Thanks to your suggestion @Luke Woodward. Indeed there was an extra unicode in the email address I was trying to compare. Hence why I couldn't get desired result. I didn't want to go the route of deleting all the users (to avoid data loss) so had to manually edit each email.

Works fine now.

4
Md Farid Uddin Kiron On

ASP.NET Core MVC _userManager.FindByEmailAsync(Input.Email) returns null despite existing user with the same email

Well based on your scenario and description along with the shared code snippet it seems that you have done most of the steps we should have done.

For instace, you are saying you have already confirmed that eamil case sensitivity you have checked,

In addition, you have already checked that your email is existing in the database and the email also coming correctly from user form submit as well.

apart from that, you have also checked _userManager.FindByEmail getting you correct value while registering the user. Up to this so far so good.

Altough, most of the initial troubleshooting you have successfully done, and I belive, its hard to reproduce your scenario at our end,because I am getting the expected value in my following method:

    [HttpPost]
    public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = await _userManager.FindByEmailAsync(model.Email);
            if (user != null)
            {
                var token = await _userManager.GeneratePasswordResetTokenAsync(user);
                var callbackUrl = Url.Action("ResetPassword", "ResetPassword", new { userId = user.Id, token }, protocol: HttpContext.Request.Scheme);
                await _emailSender.SendEmailAsync(model.Email, "Reset Password", $"Please reset your password by clicking here: {callbackUrl}");
                return View("ForgotPasswordConfirmation");
            }

           
            return View("ForgotPasswordConfirmation");
        }

        return View(model);
    }

However, after checking database connection string, other configurations if you found that everything is correct yet, you are still getting null email response. Then as a work around you get check that from AspNetUsers table which is the Identity table contining all application user info, we also can check AspNetUsers table directly. You can do as following:

bool emailExists = await _context.AspNetUsers.AnyAsync(em => em.Email == userModel.UserEmail);

enter image description here

Note: I kept my table name as AspNetUsers, just replace it with your table name. As you an see I have my DbContext like above screenshot.