Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
315 views
in Technique[技术] by (71.8m points)

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

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("[email protected]", "(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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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);
    

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...