使用 EWS 而不是 IMAP/SMTP 发送和接收电子邮件

Send & Receive email using EWS rather than IMAP/SMTP

此代码适用于使用 IMAP 和 SMTP 协议发送和接收电子邮件,但我现在需要使用 EWS(Exchange Web 服务)协议发送和接收电子邮件,以防有人在他们的帐户上禁用 IMAP/SMTP 服务.谁能告诉我我必须改变什么才能做到这一点?

using (ImapClient client = new ImapClient())
{
    client.Connect("outlook.office365.com", 993, SecureSocketOptions.Auto);
    SaslMechanism oauth2;

    if (client.AuthenticationMechanisms.Contains("OAUTHBEARER"))
        oauth2 = new SaslMechanismOAuthBearer(this.Identity.Email, this.AccessToken);
    else
        oauth2 = new SaslMechanismOAuth2(this.Identity.Email, this.AccessToken);

    client.Authenticate(oauth2);
    FolderNamespaceCollection namespaces = client.PersonalNamespaces;
    int totalCount = 0;
    IList<IMailFolder> folders = client.GetFolders(client.PersonalNamespaces[0], StatusItems.Unread | StatusItems.Count);
    foreach (IMailFolder folder in folders)
    {
        folder.Open(FolderAccess.ReadOnly);
        totalCount += folder.Search(SearchQuery.NotSeen).Count;
        folder.Close();
    }
    client.Disconnect(true);
}

using (SmtpClient client = new SmtpClient())
{
    client.Connect("smtp-mail.outlook.com", 587, SecureSocketOptions.Auto);
    SaslMechanism oauth2;
        if (client.AuthenticationMechanisms.Contains("OAUTHBEARER"))
        oauth2 = new SaslMechanismOAuthBearer(this.Identity.Email, this.AccessToken);
    else
        oauth2 = new SaslMechanismOAuth2(this.Identity.Email, this.AccessToken);

    client.Authenticate(oauth2);
    using (MimeMessage message = new MimeMessage())
    {
        message.Sender = new MailboxAddress(this.Identity.Email, this.Identity.Email);
        message.From.Add(message.Sender);
        message.To.Add(new MailboxAddress("<Recipient>", "recipient@email.com"));
        message.Subject = "SMTP OAuth Test";
        TextPart body = new TextPart
        {
            Text = "If this was received then it worked"
        };
        message.Body = body;
        client.Send(message);
    }
    client.Disconnect(true);
}

Exchange Web 服务是一个基于 XML 的网络 API,您现有的代码对通过 EWS 发送邮件没有任何好处。

我以前成功使用过https://independentsoft.de/exchangewebservices/index.html的客户端。

如果邮箱在 Office365 上,那么您可能想跳过 EWS,只使用 Microsoft Graph(因为 EWS 开始贬值 https://techcommunity.microsoft.com/t5/exchange-team-blog/upcoming-api-deprecations-in-exchange-web-services-for-exchange/ba-p/2813925

如果你使用Graph SDK https://docs.microsoft.com/en-us/graph/sdks/sdks-overview 则相对容易转换例如

获取电子邮件https://docs.microsoft.com/en-us/graph/api/user-list-messages?view=graph-rest-1.0&tabs=csharp

发送电子邮件https://docs.microsoft.com/en-us/graph/api/user-sendmail?view=graph-rest-1.0&tabs=csharp

如果您想避免重复现有的 Mimekit 代码,您可以使用 Graph SDK 以 Mime 格式发送电子邮件,例如此处

var message = new MimeMessage();
message.From.Add(MailboxAddress.Parse(mailboxName));
message.To.Add(MailboxAddress.Parse(recipient));
message.Subject = "How you doin?";

// create our message text, just like before (except don't set it as the message.Body)

var builder = new BodyBuilder();

// Set the plain-text version of the message text
builder.TextBody = @"Hey Alice"

// In order to reference inline image from the html text, we'll need to add it
// to builder.LinkedResources and then use its Content-Id value in the img src.
var image = builder.LinkedResources.Add(inlineImagePath);
image.ContentId = MimeUtils.GenerateMessageId();

// Set the html version of the message text
builder.HtmlBody = string.Format(@"<p>Hey Alice,<br>>", image.ContentId);       

// Now we just need to set the message body and we're done
message.Body = builder.ToMessageBody();
//End MimeKit Sample
var stream = new MemoryStream();
message.WriteTo(stream);

stream.Position = 0;
StringContent MessagePost = new StringContent(Convert.ToBase64String(stream.ToArray()),Encoding.UTF8, "text/plain");

GraphServiceClient graphServiceClient = new GraphServiceClient(new AuthHelp(redirectUri, scope, mailboxName, clientId));
var Message = new Message { };
var sendMailRequest = graphServiceClient.Me.SendMail(Message, null).Request().GetHttpRequestMessage();
sendMailRequest.Content = MessagePost;
sendMailRequest.Method = HttpMethod.Post;
var sendResult = graphServiceClient.HttpProvider.SendAsync(sendMailRequest).Result;