Asp.Net Identity 2.0 - How to Implement IIdentityMessageService to do Async SMTP using SmtpClient?

StackOverflow https://stackoverflow.com/questions/22797845

  •  25-06-2023
  •  | 
  •  

I've implemented a simple EmailService for Asp.Net Identity 2.0 (via the IIdentityMessageService interface.

    public class EmailService : IIdentityMessageService
{
    public Task SendAsync(IdentityMessage message)
    {
        // convert IdentityMessage to a MailMessage
        var email = 
           new MailMessage(new MailAddress("noreply@mydomain.com", "(do not reply)"), 
           new MailAddress(message.Destination))
        {
            Subject = message.Subject,
            Body = message.Body,
            IsBodyHtml = true
        };

        using (var client = new SmtpClient()) // SmtpClient configuration comes from config file
        {
            return client.SendMailAsync(email);
        }
    }
}

To send an email, I go through UserManager:

await _userManager.SendEmailAsync(user.Id, "Confirm your account","Please confirm your account by clicking this link: <a href=\"" + callbackUrl + "\">link</a>");

The problem is that I get a System.Threading.Tasks.TaskCanceledException when I call SendEmailAsync() and it's not clear why.

If I send email synchronously (client.Send(email)), everything works fine.

So my questions are:

  • How do I prevent the TaskCanceledException from getting thrown? and (assuming I can overcome this error),

  • How should I go about communicating errors during email sending back to the client (i.e., "no such user here" type responses from the SmtpClient?

有帮助吗?

解决方案

Your problem is that SmtpClient is disposed before the email is sent.

Two ways:

  • Await the SendMailAsync result

    using (var client = new SmtpClient())
    {
        await client.SendMailAsync(email);
    }
    
  • Register the SendCompleted event and dispose the SmtpClient only after the message is sent

    var client = new SmtpClient();
    client.SendCompleted += (s, e) => {
        client.Dispose();
    };
    return client.SendMailAsync(message);
    

其他提示

You must put async on method.

    public async Task SendAsync(IdentityMessage message)
    {
        using (SmtpClient client = new SmtpClient())
        {
                using (var mailMessage = new MailMessage("your@email.com", message.Destination, message.Subject, message.Body))
                {
                    await client.SendMailAsync(mailMessage);
                }
            }
        }
    }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top