I'm building my first ASP.NET Core Razor Pages application.
I have created an EmailSender
class, which implements IEmailSender
.
public class EmailSender : IEmailSender
{
private readonly EmailSettings Settings;
public EmailSender(IOptions<EmailSettings> emailSettings)
{
Settings = emailSettings.Value;
}
public async Task SendEmailAsync(string email, string subject, string htmlMessage)
{
using (MailMessage message = new MailMessage())
using (SmtpClient client = new SmtpClient())
{
client.Host = Settings.Host;
client.Port = Settings.Port;
client.Credentials = new NetworkCredential(Settings.UserName, Settings.Password);
client.EnableSsl = Settings.EnableSsl;
message.To.Add(email);
message.From = new MailAddress(Settings.FromAddress);
message.Subject = subject;
message.Body = htmlMessage;
message.IsBodyHtml = true;
await client.SendMailAsync(message);
}
await Task.CompletedTask;
}
}
And I've registered EmailSender
in Startup.cs.
public void ConfigureServices(IServiceCollection services)
{
// Default initialization...
services.AddTransient<IEmailSender, EmailSender>();
services.Configure<EmailSettings>(Configuration.GetSection("EmailSettings"));
}
My code builds with no errors.
Using breakpoints, I can see that when I run the application and click Forgot your Password, the EmailSender
constructor is called and the EmailSettings
instance has the expected values. And when I enter my email address and click Reset Password, the EmailSender
constructor is called a second time. However, EmailSender.SendEmailAsync()
is never called, and no email is sent.
I'm convinced my EmailSender
class is setup right because the constructor is being called. But I don't know how to isolate the reason SendEmailAsync()
is never called.
Does anyone have a suggestion?
You need to scaffold Identity in order to debug the code.
Right click on the Identity folder and then click
In the left menu click
Then
Now you have your razor page with code behind so click on the arrow to expand the code behind file.
In the PostAsync()
put a breakpoint on the if statement.
if (user == null || !(await _userManager.IsEmailConfirmedAsync(user))) // Breakpoint here
{
...
}
Run the application and do a Forgot Password request.
Your breakpoint will hit and you will be able to debug. It will not exit the if-statement because await _userManager.IsEmailConfirmedAsync(user)
is false.
Solve that problem by dragging the debugger outside of that loop, and let it continue. Now you will see that your Email sender will be called and your SendEmailAsync will hit.
SendEmailAsync
because the user you tried to request a password for was either non-existent or most likely, your user's email wasn't confirmed!