调试ForgotPassword方法时无法通过邮箱找到用户的排查请求
ForgotPassword Method Not Finding Existing User in ASP.NET Core Hey Raj, let's break down why your ForgotPassword method can't locate the user even though the email exists in your database. Here are the most common fixes and checks to run through:
1. Fix Case Sensitivity in Email Lookups
By default, ASP.NET Core Identity's FindByEmailAsync might perform case-sensitive comparisons. If your database stores user@example.com but you're sending User@Example.com from Postman, the lookup will fail.
Quick Fix: Normalize the Email
Convert the incoming email to lowercase before querying:
var normalizedEmail = model.Email.ToLowerInvariant(); var user = await _userManager.FindByEmailAsync(normalizedEmail);
Permanent Fix: Configure Identity to Ignore Case
Add this to your Program.cs/Startup.cs to enforce lowercase email normalization globally:
builder.Services.AddIdentity<IdentityUser, IdentityRole>(options => { options.User.EmailNormalizer = new LowerInvariantEmailNormalizer(); }) .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders();
2. Verify Model Binding is Working Correctly
Double-check that the email from Postman is actually reaching your method. Sometimes typos in JSON keys or missing properties can cause empty/incorrect values.
Add Debug Output to Confirm
Insert a debug line to see what email your method receives:
[HttpPost] public async Task<IActionResult> ForgotPassword([FromBody] RegisterDto model) { // Debug: Print the incoming email to confirm it's correct System.Diagnostics.Debug.WriteLine($"Received email: {model.Email}"); // Rest of your code... }
Also ensure your RegisterDto has a public Email property that matches the JSON key you're sending (e.g., if you send {"email": "test@example.com"}, the property should be public string Email { get; set; }).
3. Check if the User is Locked/Deactivated
If your user model includes custom fields like IsActive or IsDeleted, or uses Identity's built-in lockout features, the user might exist but be excluded from queries.
- Directly check your
AspNetUserstable in the database to confirm:LockoutEndis null (not locked out)LockoutEnabledis not preventing access- Any custom status fields (like
IsActive) are set totrue
4. Confirm You're Connected to the Right Database
It's easy to accidentally connect to a test database instead of your development instance. Check your appsettings.json connection string to ensure it points to the database where you verified the email exists.
5. Fix the Broken Email Link (Bonus!)
I noticed your email body has a syntax error in the link—this won't fix the user lookup issue, but it will ensure the reset link works once you resolve the main problem:
// Original (broken) link: // $"Click <a href=\"" + passwordResetUrl + "\"here</a> to reset your password" // Fixed version: var emailBody = $"Click <a href=\"{passwordResetUrl}\">here</a> to reset your password"; await _messageService.Send(model.Email, "Password reset", emailBody);
Modified Working Example
Here's your updated method with debug checks and fixes applied:
[HttpPost] public async Task<IActionResult> ForgotPassword([FromBody] RegisterDto model) { if (string.IsNullOrWhiteSpace(model.Email)) { return Content("Email is required"); } System.Diagnostics.Debug.WriteLine($"Received email: {model.Email}"); var normalizedEmail = model.Email.ToLowerInvariant(); var user = await _userManager.FindByEmailAsync(normalizedEmail); if (user == null) { System.Diagnostics.Debug.WriteLine($"No user found for normalized email: {normalizedEmail}"); return Content("Email id not exist"); } var passwordResetToken = await _userManager.GeneratePasswordResetTokenAsync(user); var passwordResetUrl = Url.Action("ResetPassword", "Account", new { id = user.Id, token = passwordResetToken }, Request.Scheme); var emailBody = $"Click <a href=\"{passwordResetUrl}\">here</a> to reset your password"; await _messageService.Send(model.Email, "Password reset", emailBody); return Content("Check your email for a password reset link"); }
内容的提问来源于stack exchange,提问作者Raj kumar

