使用 Exchange 中的 EWS 响应电子邮件

了解如何使用 Exchange 中的 EWS 托管 API 或 EWS 响应电子邮件。

可以使用 EWS 托管 API 或 EWS 通过答复邮件或转发给收件人来响应邮件。

表 1. 用于响应电子邮件的 EWS 托管 API 方法和 EWS 操作

任务 EWS 托管的 API 方法 EWS 操作
答复电子邮件
EmailMessage.Reply
EmailMessage.CreateReply
CreateItem,其中 Items 元素具有 ReplyToItemReplyAllToItem 的子元素。
转发电子邮件
EmailMessage.Forward
EmailMessage.CreateForward
CreateItem,其中 Items 元素具有 ForwardItem 的子元素。

使用 EWS 托管 API 回复电子邮件

EWS 托管 API 提供了两种可用于响应消息的方法: ReplyCreateReplyReply 方法仅采用两个参数:在现有正文前面追加的响应消息和一个布尔值,该值指示响应是应 (true) 还是仅发送方 (false) 。 如果需要向邮件添加其他收件人、设置响应的其他属性或添加附件,请使用 CreateReply 方法,该方法可设置 EmailMessage 对象上可用的所有一类属性

下面的代码示例演示如何使用 Reply 方法回复电子邮件。

此示例假定 service 是有效的 ExchangeService 对象,且用户已通过 Exchange 服务器的身份验证。 局部变量 ItemId 是要响应的项的 ID 。 该示例调用 FindRecentlySent 方法来 验证消息是否已标记为已答复。

// As a best practice, limit the properties returned by the Bind method to only those that are required.
PropertySet propSet = new PropertySet(BasePropertySet.IdOnly, ItemSchema.LastModifiedTime);
// Bind to the email message to reply to by using the ItemId.
// This method call results in a GetItem call to EWS.
EmailMessage message = EmailMessage.Bind(service, ItemId, propSet);
string myReply = "This is the message body of the email reply.";
bool replyToAll = false;
// Send the response message.
// This method call results in a CreateItem call to EWS.
message.Reply(myReply, replyToAll);
// Verify that the response was sent by calling FindRecentlySent.
FindRecentlySent(message);

下面的代码示例演示如何使用 CreateReply 方法响应电子邮件。

// Bind to the email message to reply to by using the ItemId.
// This method call results in a GetItem call to EWS.
EmailMessage message = EmailMessage.Bind(service, ItemId, BasePropertySet.IdOnly);
// Create the reply response message from the original email message.
// Indicate whether the message is a reply or reply all type of reply.
bool replyToAll = true;
ResponseMessage responseMessage = message.CreateReply(replyToAll);
// Prepend the reply to the message body. 
string myReply = "This is the message body of the email reply.";
responseMessage.BodyPrefix = myReply;
// Send the response message.
// This method call results in a CreateItem call to EWS.
responseMessage.SendAndSaveCopy();
// Check that the response was sent by calling FindRecentlySent.
FindRecentlySent(message);

如果需要向响应消息添加附件,请将 对 SendAndSaveCopy 方法的调用替换为以下代码。

EmailMessage reply = responseMessage.Save();
reply.Attachments.AddFileAttachment("attachmentname.txt");
reply.Update(ConflictResolutionMode.AutoResolve);
reply.SendAndSaveCopy();

使用 EWS 回复电子邮件

下面的代码示例演示如何使用 EWS 回复消息。 使用 CreateItem 操作, 将 MessageDisposition 属性设置为 SendAndSaveCopy 以发送邮件并将响应保存在“已发送邮件”文件夹中。 将 ReplyAllToItem 元素作为 Items 元素的子元素包含在邮件线程上,或包含 ReplyToItem 元素以仅答复发件人。

这也是 EWS 托管 API 在调用 ReplyCreateReply 方法时发送的 XML 请求。

<?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="https://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <t:RequestServerVersion Version=" Exchange2007_SP1" />
  </soap:Header>
  <soap:Body>
    <m:CreateItem MessageDisposition="SendAndSaveCopy">
      <m:Items>
        <t:ReplyAllToItem>
          <t:ReferenceItemId Id="AAMkADE4="
                             ChangeKey="CQAAABYA" />
          <t:NewBodyContent BodyType="HTML">This is the message body of the email reply.</t:NewBodyContent>
        </t:ReplyAllToItem>
      </m:Items>
    </m:CreateItem>
  </soap:Body>
</soap:Envelope>

服务器使用 CreateItemResponse 消息响应 CreateItem 请求,该消息包含 NoErrorResponseCode 元素值,指示已成功创建并发送回复。

如果需要向响应消息添加附件,请调用上面指定的 CreateItem 操作,但将 MessageDisposition 更改为 SaveOnly。 然后调用 CreateAttachment 操作,然后调用 SendItem 操作。

使用 EWS 托管 API 转发电子邮件

EWS 托管 API 提供了两种可用于转发消息的方法: ForwardCreateForwardForward 方法仅采用两个参数:要附加到现有正文的消息,以及一个数组或收件人集合,具体取决于你选择使用的重载。 如果需要向要转发的邮件添加附件,或对新邮件设置其他属性,请使用 CreateForward 方法,该方法可设置 EmailMessage 对象上可用的所有属性。

下面的代码示例演示如何使用 Forward 方法将电子邮件转发给一个收件人。

此示例假定 service 是有效的 ExchangeService 对象,且用户已通过 Exchange 服务器的身份验证。 局部变量 ItemId 是要转发的项的 ID 。 该示例调用 FindRecentlySent 方法 以验证消息是否已标记为已转发。

// Bind to the email message to reply to by using the ItemId.
// This method call results in a GetItem call to EWS.
EmailMessage message = EmailMessage.Bind(service, ItemId, BasePropertySet.IdOnly);
string myForward = "This is the message body of the forwarded email.";
// Send the response message.
// This method call results in a CreateItem call to EWS.
message.Forward(myForward, "sadie@contoso.com");
// Verify that the forwarded response was sent by calling FindRecentlySent.
FindRecentlySent(message);

下面的代码示例演示如何使用 CreateForward 方法将电子邮件转发给一个收件人。

// Bind to the email message to reply to by using the ItemId.
// This method call results in a GetItem call to EWS.
EmailMessage message = EmailMessage.Bind(service, ItemId, BasePropertySet.IdOnly);
// Create the reply response message from the original email message.
// Indicate whether the message is a reply or reply all type of reply.
ResponseMessage forwardMessage = message.CreateForward();
// Set properties on the email message.
forwardMessage.ToRecipients.Add("sadie@contoso.com");
forwardMessage.Body = "Sadie,<br><br>I thought you'd be interested in this thread.<br><br>-Mack";
// Send and save a copy of the replied email message in the default Sent Items folder. 
forwardMessage.SendAndSaveCopy();
// Verify that the forwarded message was sent by calling FindRecentlySent.
FindRecentlySent(message);

如果需要向转发的邮件添加附件,请将对 SendAndSaveCopy 方法的调用替换为以下代码。

EmailMessage forward = forwardMessage.Save();
forward.Attachments.AddFileAttachment("attachmentname.txt");
forward.Update(ConflictResolutionMode.AutoResolve);
forward.SendAndSaveCopy();

使用 EWS 转发电子邮件

下面的代码示例演示如何使用 EWS 转发消息。 使用 CreateItem 操作, 将 MessageDisposition 属性设置为 SendAndSaveCopy 以发送邮件并将响应保存在“已发送邮件”文件夹中。 ForwardItem 元素指示该项是转发的消息。

这也是 EWS 托管 API 在调用 ForwardCreateForward 方法时发送的 XML 请求。

<?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="https://schemas.xmlsoap.org/soap/envelope/">
  <soap:Header>
    <t:RequestServerVersion Version="Exchange2007_SP1" />
  </soap:Header>
  <soap:Body>
    <m:CreateItem MessageDisposition="SendAndSaveCopy">
      <m:Items>
        <t:ForwardItem>
          <t:ToRecipients>
            <t:Mailbox>
              <t:EmailAddress>sadie@contoso.com</t:EmailAddress>
            </t:Mailbox>
          </t:ToRecipients>
          <t:ReferenceItemId Id="AAAMkADE="
                             ChangeKey="CQAAABYA" />
          <t:NewBodyContent BodyType="HTML">This is the message body of the forwarded email.</t:NewBodyContent>
        </t:ForwardItem>
      </m:Items>
    </m:CreateItem>
  </soap:Body>
</soap:Envelope>

服务器使用 CreateItemResponse 消息响应 CreateItem 请求,该消息包含 NoError的 ResponseCode 元素值,该值指示已成功创建并发送转发的消息。

如果需要向响应消息添加附件,请调用 CreateItem 操作,但将 MessageDisposition 更改为 SaveOnly。 然后调用 CreateAttachment 操作,然后调用 SendItem 操作。

使用 EWS 托管 API 查找上次答复或转发的消息

下面的代码示例演示如何查找执行的最后一个谓词,以及对指定项执行最后一个谓词的时间。 此方法是从本主题中的其他 EWS 托管 API 代码示例调用的,用于验证你答复或转发的项目是否已标记为“已答复”或“已在收件箱中转发”。

该示例使用 PidTagLastVerbExecuted (0x10820003) 扩展属性来确定邮件是答复、全部答复还是转发, PidTagLastVerbExecutionTime (0x10820040) 扩展属性来确定何时发送答复或转发。

public static void FindRecentlySent(EmailMessage messageToCheck)
{
    // Create extended property definitions for PidTagLastVerbExecuted and PidTagLastVerbExecutionTime.
    ExtendedPropertyDefinition PidTagLastVerbExecuted = new ExtendedPropertyDefinition(0x1081, MapiPropertyType.Integer);
    ExtendedPropertyDefinition PidTagLastVerbExecutionTime = new ExtendedPropertyDefinition(0x1082, MapiPropertyType.SystemTime);
    PropertySet propSet = new PropertySet(BasePropertySet.IdOnly, EmailMessageSchema.Subject, PidTagLastVerbExecutionTime, PidTagLastVerbExecuted);
    messageToCheck = EmailMessage.Bind(service, messageToCheck.Id, propSet);
    // Determine the last verb executed on the message and display output.
    object responseType;
    if (messageToCheck.TryGetProperty(PidTagLastVerbExecuted, out responseType))
    {
        object ReplyTime = null;
        switch (((Int32)responseType))
        {
            case 102: Console.WriteLine("A reply was sent to the '" + messageToCheck.Subject.ToString() + "' email message at");
                break;
            case 103: Console.WriteLine("A reply all was sent to the '" + messageToCheck.Subject.ToString() + "' email message at");
                break;
            case 104: Console.WriteLine("The '" + messageToCheck.Subject.ToString() + "' email message was forwarded at");
                break;
        }
        if (messageToCheck.TryGetProperty(PidTagLastVerbExecutionTime, out ReplyTime))
        {
            Console.WriteLine(((DateTime)ReplyTime).ToString() + ".");
        }
    }
    else
    {
        Console.WriteLine("No changes were made to  '" + messageToCheck.Subject.ToString() + "'.");
    }
}

另请参阅