c# – 如何使用带有Windows身份验证和没有邮箱的身份的EWS发送和保存电子邮件?

我的情况是这样的:

>我使用服务帐户和Windows身份验证连接到Exchange Web服务(EWS)
>我不使用模拟
>服务帐户没有邮箱
>我连接到邮箱’MyMailbox’来阅读和发送电子邮件.每当我发送电子邮件时,我都会使用SendAndSaveCopy(),指定要保存的MyMailbox的SentItems文件夹.如果没有指定文件夹SendAndSaveCopy()失败,可以理解,因为没有邮箱链接到我的服务帐户,它可以保存电子邮件.
>我有时想要发送为或代表其他用户发送,因此我将From属性设置为该用户的其他主用SMTP地址.

在这种情况下,一切正常,直到我发送带有附件的电子邮件.在这种情况下,它失败,ResponseCode = ErrorMissingEmailAddress和MessageText =当作为没有邮箱的帐户发出请求时,您必须为任何可识别的文件夹ID指定邮箱主SMTP地址.

查看从SendAndSaveCopy()发送的SOAP消息,当我有附件时,我可以看到它完全不同 – 请注意MessageDisposition =“SaveOnly”

  <?xml version="1.0" encoding="utf-8"?>
  <soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header>
      <t:RequestServerVersion Version="Exchange2010_SP2" />
    </soap:Header>
    <soap:Body>
      <m:CreateItem MessageDisposition="SaveOnly">
        <m:Items>
          <t:Message>
            <t:Subject>My test email subject</t:Subject>
            <t:Body BodyType="HTML">....

而在没有附件的情况下发送时,它有< m:CreateItem MessageDisposition =“SendAndSaveCopy”>. EWS首先保存电子邮件然后发送它似乎是合理的.确实API doc

This method does not work if the message has unsaved attachments. In that case, the message must first be saved and then sent.

虽然当我作为具有邮箱的标识连接时,SendAndSaveCopy()似乎工作正常,而MSDN example code显示调用SendAndSaveCopy()而没有任何临时步骤.该示例明确指出SendAndSaveCopy()导致对EWS的三次调用:CreateItem,CreateAttachment,SendItem.

我的主要问题是:我应该如何调用EWS来实现与SendAndSaveCopy()相同的功能,但是当我有附件时?

第二个问题:这是一个错误吗?当给定一个folderId使用该文件夹进行CreateItem调用时,不应该发送SendAndSaveCopy()吗?

我正在使用EWS 15.0.0.0并指定Exchange2010_SP2 api版本.

更新:

在进一步检查时,我发现当有附件时,EWS Managed API也会为SendAndSaveCopy()发出多个EWS调用,而我正在使用用户名&密码验证.我看到两条EWS消息:

>第一个有< m:CreateItem MessageDisposition =“SaveOnly”>并且特别是没有SavedItemFolderId.那么它在哪里保存!?我的猜测是它被保存到当前用户邮箱的默认位置,这对我的Windows身份验证方案失败,因为没有当前用户的邮箱.
>来自此的响应为已保存的邮件消息及其保存的附件提供ItemId.
>第二个EWS呼叫具有< m:SendItem SaveItemToFolder =“true”>并设置SavedItemFolderId

我仍然认为这是SendAndSaveCopy()中的错误或缺少的功能:它应该使用指定的文件夹位置来保存临时消息.但无论如何,我应该使用什么EWS托管API调用来获得所需的效果?

最佳答案

The first has and notably no SavedItemFolderId. So where is it saved!? My guess is it’s saved to a default location for the current user’s mailbox, which fails for my windows auth scenario because there’s no current user’s mailbox.

默认保存位置是您正在使用的安全主体的邮箱的草稿文件夹. EWS是一个客户端API,因此您看到的行为是围绕您希望普通电子邮件客户端执行的操作而设计的.

如果要在没有中间步骤的情况下发送带附件的消息,您可以使用附件对要发送的消息进行MIME编码,然后通过一次调用发送它,例如.

EmailMessage test2 = new EmailMessage(service);
String bodyContent = "<html><head><meta http-equiv=\"Content-type\" content=\"text/html;charset=UTF-8\">Hello World</head><body></body></html> ";

CDO.Message msMessage = new CDO.Message();
msMessage.BodyPart.Charset = "UTF-8";
msMessage.HTMLBody = bodyContent;
msMessage.HTMLBodyPart.Charset = "UTF-8";
msMessage.AddAttachment("c:\\temp\\Document.docx");
ADODB.Stream asMessageStream = msMessage.GetStream();
asMessageStream.Type = ADODB.StreamTypeEnum.adTypeBinary;
byte[] bdBinaryData1 = new byte[asMessageStream.Size];
bdBinaryData1 = (byte[])asMessageStream.Read(asMessageStream.Size);
service.TraceEnabled = true;
test2.MimeContent = new MimeContent("UTF-8", bdBinaryData1);
test2.ToRecipients.Add("user@domain.com");
test2.Subject = "test";
test2.SendAndSaveCopy();

干杯
狭谷

点赞