C# 如何将 Await 添加到此函数 - SendEmailAsync - Dot Net Core 中的 MailKit

C# how to add Await to this function - SendEmailAsync - MailKit in Dot Net Core

我有基于 MailKit 的代码。在哪里添加 await 关键字?

public async Task SendEmailAsync(string email, string subject, string mess)
{
    var message = new MimeMessage();
    message.From.Add(new MailboxAddress("Joey Tribbiani", "joey@friends.com"));
    message.To.Add(new MailboxAddress("Mrs. Chanandler Bong", "chandler@friends.com"));
    message.Subject = "How you doin'?";

    message.Body = new TextPart("plain")
    {
        Text = @"Hey Chandler"
    };

    using (var client = new SmtpClient())
    {
        // For demo-purposes, accept all SSL certificates (in case the server supports STARTTLS)
        client.ServerCertificateValidationCallback = (s, c, h, e) => true;

        client.Connect("smtp.friends.com", 587, false);

        // Note: since we don't have an OAuth2 token, disable
        // the XOAUTH2 authentication mechanism.
        client.AuthenticationMechanisms.Remove("XOAUTH2");

        // Note: only needed if the SMTP server requires authentication
        client.Authenticate("joey", "password");

        client.Send(message);
        client.Disconnect(true);
    }
}

这是一个类似的实现(但我找不到使它工作的凭据)所以我改为上面的

    public async Task SendEmailAsync(string email, string subject, string message)
    {
        using (var client = new HttpClient { BaseAddress = new Uri("smtp.gmail.com") })
        {
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
                Convert.ToBase64String(Encoding.ASCII.GetBytes("api:key-*")));


            var content = new FormUrlEncodedContent(new[]
            {
                new KeyValuePair<string, string>("from", "postmaster@sandbox*.mailgun.org"),
                new KeyValuePair<string, string>("to", email),
                new KeyValuePair<string, string>("subject", subject),
                new KeyValuePair<string, string>("text", message)
            });

            await client.PostAsync("sandbox*.mailgun.org/messages", content).ConfigureAwait(false);
        }
    }

如果您使用的是 .Net 核心和 MailKit,您应该引用 MailKit 库并通过它们发送。我用于发送电子邮件的 MailKit class 如下:

using System;
using System.Threading;
using MailKit.Security;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using MimeKit;
using SmtpClient = MailKit.Net.Smtp.SmtpClient;

namespace App.Email
{
    public class MailKit : IMailKit
    {
        private readonly ILogger<MailKit> _logger;
        private readonly Settings _settings;

        public MailKit(ILogger<MailKit> logger, IOptions<Settings> settings)
        {
            _logger = logger;
            _settings = settings.Value;
        }

        /// <summary>
        /// Sends an email asynchronously using SMTP
        /// </summary>
        /// <param name="toEmailAddress"></param>
        /// <param name="subject"></param>
        /// <param name="bodyHtml"></param>
        /// <param name="bodyText"></param>
        /// <param name="retryCount"></param>
        /// <param name="toName"></param>
        public async void Send(string toName, string toEmailAddress, string subject, string bodyHtml, string bodyText, int retryCount = 4)
        {
            var message = new MimeMessage();

            message.From.Add(new MailboxAddress(_settings.MailKitFromName, _settings.MailKitFromAddress));

            message.To.Add(new MailboxAddress(toName, toEmailAddress));

            message.Subject = subject;
            var builder = new BodyBuilder
            {
                TextBody = bodyText,
                HtmlBody = bodyHtml
            };
            message.Body = builder.ToMessageBody();

            for (var count = 1; count <= retryCount; count++)
            {
                try
                {
                    using (var client = new SmtpClient())
                    {
                        client.LocalDomain = _settings.MailKitLocalDomain;
                        client.Authenticate(_settings.MailKitUsername, _settings.MailKitPassword);

                        SecureSocketOptions secureSocketOptions;

                        if (!Enum.TryParse(_settings.MailKitSecureSocketOption, out secureSocketOptions))
                        {
                            secureSocketOptions = SecureSocketOptions.Auto;
                        }

                        await client.ConnectAsync(_settings.MailKitHost, _settings.MailKitPort, secureSocketOptions).ConfigureAwait(false);
                        await client.SendAsync(message).ConfigureAwait(false);
                        await client.DisconnectAsync(true).ConfigureAwait(false);
                        return;
                    }
                }
                catch (Exception exception)
                {
                    _logger.LogError(0, exception, "MailKit.Send failed attempt {0}", count);
                    if (retryCount >= 0)
                    {
                        throw;
                    }
                    await Task.Delay(count * 1000);
                }
            }
        }
    }
}

界面

namespace App.Email
{
    public interface IMailKit
    {
        void Send(string toName, string toEmailAddress, string subject, string bodyHtml, string bodyText, int retryCount = 4);
    }
}

您可以这样使用 async functions

public class Notification
{
    public Notification() { }
    private string emailSubject,receiverEmail,emailBody;

    public string EmailSubject { get => emailSubject; set => emailSubject = value; }
    public string ReceiverEmail { get => receiverEmail; set => receiverEmail = value; }
    public string EmailBody { get => emailBody; set => emailBody = value; }

    public async Task<bool> sendEmail(){
        try
        {
            var message = new MimeMessage();
            message.From.Add(new MailboxAddress("Smart Living", "smartliving321@gmail.com"));
            message.To.Add(new MailboxAddress("Person", receiverEmail));
            message.Subject = emailSubject;
            message.Body = new TextPart("plain")
            {
                Text = emailBody
            };
            using (var client = new SmtpClient())
            {
                await client.ConnectAsync("smtp.gmail.com", 587, false);
                await client.AuthenticateAsync("smartliving321@gmail.com", "living@smart1122");
                await client.SendAsync(message);
                await client.DisconnectAsync(true);
                //                client.ServerCertificateValidationCallback=();
            };
            return true;
        }
        catch (Exception ex) {

            return false;
        }
    }
}

这是我的简单解决方案,现在我可以在 asp 核心项目中使用 IdentityServer 使用 MailKit 发送电子邮件。

public class EmailSender : Microsoft.AspNetCore.Identity.UI.Services.IEmailSender
{
    private readonly EmailConfiguration _emailConfig;
    public EmailSender(EmailConfiguration emailConfig)
    {
        _emailConfig = emailConfig;
    }

    public Task SendEmailAsync(string email, string subject, string htmlMessage)
    {
        var message = new MimeMessage();
        message.From.Add(new MailboxAddress(_emailConfig.FromName, _emailConfig.FromEmail));
        message.To.Add(new MailboxAddress(email.Trim().ToLower(), email.Trim().ToLower()));
        message.Subject = subject;
        message.Body = new TextPart("html") { Text = htmlMessage };

        using (var client = new SmtpClient())
        {
            try
            {
                client.Connect(_emailConfig.SmtpServer, _emailConfig.Port, MailKit.Security.SecureSocketOptions.SslOnConnect);
                client.Authenticate(_emailConfig.UserName, _emailConfig.Password);
                client.Send(message);
                client.Disconnect(true);
                return Task.FromResult(true);
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
            }
        }
    }

并在 startup.cs -> ConfigureServices

        var emailConfig = Configuration.GetSection("EmailConfiguration")
            .Get<EmailService.EmailConfiguration>();
        services.AddSingleton(emailConfig);
        services.AddScoped<IEmailSender, EmailService.EmailSender>();