Search code examples
c#sendgridasp.net-core-identity

Asp.Net Core Identity SendGrid mails are not being sent


I am trying to find out why the account verification email is not being sent from my app when creating a new user account.

I was able to send two emails on one of my first attempts. The emails ended up in my spam filter, but they did get through. I do not know what may have changed since then.

Checking the SendGrid control panel, I can confirm that two emails was sent the first day I tried it, but none of my later attempts have generated any emails.

This article suggests to set a breakpoint on EmailSender.Execute. I have done that, and found that it is indeed not being hit. How do I debug further?

The SendGrid account information is specified in secrets.json:

{
  "SendGridUser": "{account name}",
  "SendGridKey": "{api-key}"
}

A service is configured in Startup.cs:

services.AddTransient<IEmailSender, EmailSender>();
services.Configure<AuthMessageSenderOptions>(Configuration);

AuthMessageSenderOptions:

public class AuthMessageSenderOptions
{
    public string SendGridUser { get; set; }
    public string SendGridKey { get; set; }
}

The EmailSender service:

public class EmailSender : IEmailSender
{
    public EmailSender(IOptions<AuthMessageSenderOptions> optionsAccessor)
    {
        Options = optionsAccessor.Value;
    }

    public AuthMessageSenderOptions Options { get; } //set only via Secret Manager

    public Task SendEmailAsync(string email, string subject, string message)
    {
        return Execute(Options.SendGridKey, subject, message, email);
    }

    public Task Execute(string apiKey, string subject, string message, string email)
    {
        var client = new SendGridClient(apiKey);
        var msg = new SendGridMessage()
        {
            From = new EmailAddress("[email protected]", Options.SendGridUser),
            Subject = subject,
            PlainTextContent = message,
            HtmlContent = message
        };
        msg.AddTo(new EmailAddress(email));

        // Disable click tracking.
        // See https://sendgrid.com/docs/User_Guide/Settings/tracking.html
        msg.SetClickTracking(false, false);

        return client.SendEmailAsync(msg);
    }
}

A user is created like this:

// user is an ApplicationUser-object
IdentityResult result = await userManager.CreateAsync(auto.Map<ApplicationUser>(user), "P&55w0rd");
if (result.Succeeded)
{
    ApplicationUser u = await userManager.FindByNameAsync(user.UserName);
    if (u != null)
    { 
        // newUser.RN is the role name to be assigned to the new user
        await userManager.AddToRoleAsync(u, newUser.RN);
    }
    return RedirectToAction("Details", new { id = user.Id });
}
else
{
    foreach (var error in result.Errors)
    {
        ModelState.AddModelError("", error.Description);
    }
}

A new user is created, added to the role and we are redirected to Users/Details/{id}, but the account verification email is not sent.


Solution

  • I'd be surprised if Identity does it by default, only by setting up the EmailSender. You do not seem to provide any logic for the confirmation and nowhere to call the EmailSender.

    You need to inject the IEmailSender as a service in your controller where you are creating the user, and add the logic to generate a confirmation token and actually send the email.

    I'd expect something in the lines of:

    var token = await userManager.GenerateEmailConfirmationTokenAsync(user);
    var confirmationLink = Url.Action(nameof(ConfirmEmail), "Account", 
       new { token , email = user.Email }, 
       Request.Scheme);
    await _emailSender.SendEmailAsync(user.Email, "Confirmation email link", confirmationLink);
    

    Of course you could further look how to make your email prettier, but that's the core of it.

    Also, just to make sure that you have the whole picture, Identity does not also provide an email implementation by default, you also have to set it up: https://learn.microsoft.com/en-us/aspnet/core/security/authentication/accconfirm?view=aspnetcore-3.1&tabs=visual-studio#install-sendgrid