通过在 Exchange 中使用 EWS 以代理身份访问电子邮件

了解如何使用 Exchange 中的 EWS 托管 API 或 EWS 作为代理人访问电子邮件。

可以使用 EWS 托管 API 或 EWS 向用户代理授予对邮箱所有者收件箱文件夹的访问权限。 然后,代理人可以代表邮箱所有者创建会议请求,搜索电子邮件,并根据邮箱所有者的收件箱文件夹检索、更新和删除电子邮件。

作为代理人,你使用的方法和操作访问邮箱所有者的“收件箱”文件夹与你用于访问没有代理人访问权限的收件箱文件夹的方法和操作相同。 main区别在于,你必须使用显式访问权限来查找或创建电子邮件项目,然后在确定项目 ID 后,可以使用隐式访问来获取、更新或删除项目。

表 1. 用于以委托身份访问电子邮件的 EWS 托管 API 方法和 EWS 操作

若要… 使用此 EWS 托管 API 方法… 使用此 EWS 操作…
以代理人身份创建和发送电子邮件
EmailMessage.保存FolderId 参数提供对邮箱所有者的 Drafts 文件夹的 显式访问 的位置
EmailMessage.SendAndSaveCopy,其中 FolderId 参数提供对邮箱所有者的“已发送邮件”文件夹的显式访问权限
CreateItem,其中 邮箱 元素指定邮箱所有者的 EmailAddress
SendItem,其中 Mailbox 元素指定邮箱所有者的 EmailAddress
创建多个电子邮件作为代理人
ExchangeService.CreateItems,其中 FolderId 参数提供对邮箱所有者的收件箱文件夹的显式访问
CreateItem,其中 邮箱 元素指定邮箱所有者的 EmailAddress
以代理人身份搜索或查找电子邮件
ExchangeService.FindItems,其中 FolderId 参数提供对邮箱所有者的收件箱文件夹的显式访问权限
FindItem,其中 邮箱 元素指定邮箱所有者的 EmailAddress
以代理人身份获取电子邮件
EmailMessage.Bind
GetItem
以代理人身份更新电子邮件
EmailMessage.Bind 后跟 EmailMessage.Update
GetItem,然后是 UpdateItem
删除作为代理人的电子邮件
EmailMessage.Bind 后跟 EmailMessage.Delete
GetItem,然后是 DeleteItem

以代理人身份处理电子邮件时,请记住以下事项:

  • 如果代理人只需要处理会议请求和响应,则代理不需要访问“收件箱”文件夹。 有关详细信息,请参阅 以代理人身份访问日历的先决条件任务

  • 当收件人收到代表邮箱所有者发送的邮件时,发件人将显示为“代表邮箱所有者委托”。

注意

在本文的代码示例中, primary@contoso.com 是邮箱所有者。

先决条件任务

必须先将用户 添加为具有 邮箱所有者收件箱文件夹权限的代理人,然后用户才能以代理人身份访问邮箱所有者的“收件箱”文件夹。

使用 EWS 托管 API 以委托身份创建和发送电子邮件

使用 EWS 托管 API,可以使用代理用户的服务对象代表邮箱所有者创建和发送电子邮件。 此示例演示如何使用 Save 方法将邮件保存在邮箱所有者的“草稿”文件夹中,然后使用 SendAndSaveCopy 方法发送邮件并将邮件保存在邮箱所有者的“已发送邮件”文件夹中。

此示例假定 服务 是代理的有效 ExchangeService 对象,并且已向代理授予 邮箱所有者的“收件箱”、“草稿”和“已发送邮件”文件夹的相应权限

public static void DelegateAccessCreateEmail(ExchangeService service)
{
    // Create an email message and provide it with connection 
    // configuration information by using an ExchangeService 
    // object named service.
    EmailMessage message = new EmailMessage(service);
    // Set properties on the email message.
    message.Subject = "Company Soccer Team";
    message.Body = "Are you interested in joining?";
    message.ToRecipients.Add("sadie@contoso.com");
    // Save the email to the mailbox owner's Drafts folder.
    // This method call results in a CreateItem call to EWS.
    // The FolderId parameter contains the context for the 
    // mailbox owner's Inbox folder. Any additional actions 
    // taken on this message will be performed in the mailbox 
    // owner's mailbox. 
    message.Save(new FolderId(WellKnownFolderName.Drafts, new Mailbox("primary@contoso.com")));
    // Send the email and save the message in the mailbox owner's 
    // Sent Items folder.
    // This method call results in a SendItem call to EWS.
    message.SendAndSaveCopy(new FolderId(WellKnownFolderName.SentItems, new Mailbox("primary@contoso.com")));
    Console.WriteLine("An email with the subject '" + message.Subject + "' has been sent to '" 
    + message.ToRecipients[0] + "' and saved in the Sent Items folder of the mailbox owner.");
}

使用 EWS 以代理人身份创建和发送电子邮件

EWS 使你能够使用代理用户的服务对象来代表邮箱所有者创建和发送电子邮件。 此示例演示如何使用 CreateItem 操作创建电子邮件和 SendItem 操作发送时间并将其保存在邮箱所有者的“已发送邮件”文件夹中。

这也是使用 Save 方法 创建和发送电子邮件时 EWS 托管 API 发送的第一个 XML 请求。

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
               xmlns:t="https://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="SaveOnly">
      <m:SavedItemFolderId>
        <t:DistinguishedFolderId Id="drafts">
          <t:Mailbox>
            <t:EmailAddress>primary@contoso.com</t:EmailAddress>
          </t:Mailbox>
        </t:DistinguishedFolderId>
      </m:SavedItemFolderId>
      <m:Items>
        <t:Message>
          <t:Subject>Company Soccer Team</t:Subject>
          <t:Body BodyType="HTML">Are you interested in joining?</t:Body>
          <t:ToRecipients>
            <t:Mailbox>
              <t:EmailAddress>sadie@contoso.com</t:EmailAddress>
            </t:Mailbox>
          </t:ToRecipients>
        </t:Message>
      </m:Items>
    </m:CreateItem>
  </soap:Body>
</soap:Envelope>

服务器使用 CreateItemResponse 消息响应 CreateItem 请求,该邮件包含 NoError的 ResponseCode 元素值,该值指示已成功创建和保存电子邮件。 响应还包含新创建的电子邮件的项目 ID。

为了提高可读性, 已缩短 ItemId 值。

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:ServerVersionInfo MajorVersion="15"
                         MinorVersion="0"
                         MajorBuildNumber="893"
                         MinorBuildNumber="17"
                         Version="V2_10"
                         xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
                         xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
                         xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
  </s:Header>
  <s:Body>
    <m:CreateItemResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
                          xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
      <m:ResponseMessages>
        <m:CreateItemResponseMessage ResponseClass="Success">
          <m:ResponseCode>NoError</m:ResponseCode>
          <m:Items>
            <t:Message>
              <t:ItemId Id="iNRaAAA="
                        ChangeKey="CQAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAABiQPU" />
            </t:Message>
          </m:Items>
        </m:CreateItemResponseMessage>
      </m:ResponseMessages>
    </m:CreateItemResponse>
  </s:Body>
</s:Envelope>

接下来,使用 SendItem 操作代表邮箱所有者发送邮件,并将其保存在邮箱所有者的“已发送邮件”文件夹中。

为了提高可读性, 已缩短 ItemId 值。

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
               xmlns:t="https://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:SendItem SaveItemToFolder="true">
      <m:ItemIds>
        <t:ItemId Id="iNRaAAA="
                  ChangeKey="CQAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAABiQPU" />
      </m:ItemIds>
      <m:SavedItemFolderId>
        <t:DistinguishedFolderId Id="sentitems">
          <t:Mailbox>
            <t:EmailAddress>primary@contoso.com</t:EmailAddress>
          </t:Mailbox>
        </t:DistinguishedFolderId>
      </m:SavedItemFolderId>
    </m:SendItem>
  </soap:Body>
</soap:Envelope>

服务器使用 SendItemResponse 邮件响应 SendItem 请求,该邮件包含 NoError的 ResponseCode 元素值,指示电子邮件已成功发送并保存到邮箱所有者的“已发送邮件”文件夹。

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:ServerVersionInfo MajorVersion="15"
                         MinorVersion="0"
                         MajorBuildNumber="893"
                         MinorBuildNumber="17"
                         Version="V2_10"
                         xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
                         xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
                         xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
  </s:Header>
  <s:Body>
    <m:SendItemResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
                        xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
      <m:ResponseMessages>
        <m:SendItemResponseMessage ResponseClass="Success">
          <m:ResponseCode>NoError</m:ResponseCode>
        </m:SendItemResponseMessage>
      </m:ResponseMessages>
    </m:SendItemResponse>
  </s:Body>
</s:Envelope>

使用 EWS 托管 API 以代理人身份搜索电子邮件

若要搜索电子邮件,必须使用包含 FolderId 参数的 ExchangeService.FindItems 方法之一,以便指定邮箱所有者的“收件箱”文件夹。

static void DelegateAccessSearchEmailWithFilter(ExchangeService service)
{
    // Limit the result set to 10 items.
    ItemView view = new ItemView(10);
    // Define the search filter.
    SearchFilter.ContainsSubstring filter = new SearchFilter.ContainsSubstring(ItemSchema.Subject, 
        "soccer", ContainmentMode.Substring, ComparisonMode.IgnoreCase);
    view.PropertySet = new PropertySet(ItemSchema.Subject,
                                       ItemSchema.DateTimeReceived,
                                       EmailMessageSchema.IsRead);
    // Item searches do not support deep traversal.
    view.Traversal = ItemTraversal.Shallow;
    // Sorting.
    view.OrderBy.Add(ItemSchema.DateTimeReceived, SortDirection.Descending);
    try
    {
        // Call FindItems to find matching Inbox items. 
        // The parameters of FindItems must denote the mailbox owner,
        // mailbox, and Inbox folder.
        // This call results in a FindItem call to EWS.
        FindItemsResults<Item> results = service.FindItems(new 
            FolderId(WellKnownFolderName.Inbox, "primary@contoso.com"), 
            filter, view);
        foreach (Item item in results.Items)
        {
            Console.WriteLine("Subject: {0}", item.Subject);
            Console.WriteLine("Id: {0}", item.Id.ToString());
            if (item is EmailMessage)
            {
                EmailMessage message = item as EmailMessage;
                Console.WriteLine("Read: {0}", message.IsRead.ToString());
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine("Exception while enumerating results: {0}", ex.Message);
    }
}

在 FindItems 调用返回具有 ID 的响应后,可以使用 ID 和隐式访问来获取、更新或删除该电子邮件,并且无需指定邮箱所有者的 SMTP 地址。

使用 EWS 以代理人身份搜索电子邮件

EWS 使你能够使用委托用户的服务对象来搜索满足一组搜索条件的电子邮件。 此示例演示如何使用 FindItem 操作在所有者的收件箱文件夹中查找主题中包含单词“足球”的邮件。

这也是搜索电子邮件时 EWS 托管 API 发送 XML 请求。

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
               xmlns:t="https://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:FindItem Traversal="Shallow">
      <m:ItemShape>
        <t:BaseShape>IdOnly</t:BaseShape>
        <t:AdditionalProperties>
          <t:FieldURI FieldURI="item:Subject" />
          <t:FieldURI FieldURI="item:DateTimeReceived" />
          <t:FieldURI FieldURI="message:IsRead" />
        </t:AdditionalProperties>
      </m:ItemShape>
      <m:IndexedPageItemView MaxEntriesReturned="10"
                             Offset="0"
                             BasePoint="Beginning" />
      <m:Restriction>
        <t:Contains ContainmentMode="Substring"
                    ContainmentComparison="IgnoreCase">
          <t:FieldURI FieldURI="item:Subject" />
          <t:Constant Value="soccer" />
        </t:Contains>
      </m:Restriction>
      <m:SortOrder>
        <t:FieldOrder Order="Descending">
          <t:FieldURI FieldURI="item:DateTimeReceived" />
        </t:FieldOrder>
      </m:SortOrder>
      <m:ParentFolderIds>
        <t:DistinguishedFolderId Id="inbox">
          <t:Mailbox>
            <t:EmailAddress>primary@contoso.com</t:EmailAddress>
          </t:Mailbox>
        </t:DistinguishedFolderId>
      </m:ParentFolderIds>
    </m:FindItem>
  </soap:Body>
</soap:Envelope>

服务器使用 FindItemResponse 消息来响应 FindItem 请求,其中包含 NoErrorResponseCode 元素值,指示已成功完成搜索。 响应包含满足搜索条件的任何电子邮件的 Message 元素。 在这种情况下,仅找到一封电子邮件。

为了便于阅读,已缩短 ItemId 元素的值。

<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="https://schemas.xmlsoap.org/soap/envelope/">
  <s:Header>
    <h:ServerVersionInfo MajorVersion="15"
                         MinorVersion="0"
                         MajorBuildNumber="893"
                         MinorBuildNumber="17"
                         Version="V2_10"
                         xmlns:h="https://schemas.microsoft.com/exchange/services/2006/types"
                         xmlns="https://schemas.microsoft.com/exchange/services/2006/types"
                         xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
  </s:Header>
  <s:Body>
    <m:FindItemResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
                        xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
      <m:ResponseMessages>
        <m:FindItemResponseMessage ResponseClass="Success">
          <m:ResponseCode>NoError</m:ResponseCode>
          <m:RootFolder IndexedPagingOffset="1"
                        TotalItemsInView="1"
                        IncludesLastItemInRange="true">
            <t:Items>
              <t:Message>
                <t:ItemId Id="iNwoAAA="
                          ChangeKey="CQAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAABiQuu" />
                <t:Subject>Soccer team</t:Subject>
                <t:DateTimeReceived>2014-03-10T06:16:55Z</t:DateTimeReceived>
                <t:IsRead>false</t:IsRead>
              </t:Message>
            </t:Items>
          </m:RootFolder>
        </m:FindItemResponseMessage>
      </m:ResponseMessages>
    </m:FindItemResponse>
  </s:Body>
</s:Envelope>

现在,你已获得符合条件的电子邮件的 ItemId ,可以使用 ItemId隐式访问 来获取、更新或删除该电子邮件,并且无需指定邮箱所有者的 SMTP 地址。

使用 EWS 托管 API 以委托身份获取、更新或删除电子邮件项目

可以使用 EWS 托管 API 获取、更新或删除电子邮件,其方式与不使用委托访问时执行这些操作的方式相同。 唯一的区别在于 ,ExchangeService 对象适用于委托用户。 Bind 方法调用中包含的项目 ID 唯一标识邮箱存储中邮箱所有者的“收件箱”文件夹中的项目。

表 2. 使用电子邮件作为委托的 EWS 托管 API 方法

任务 EWS 托管的 API 方法 代码示例
获取电子邮件
绑定
使用 EWS 托管 API 获取项
更新电子邮件
绑定,然后是 更新
使用 EWS 托管 API 更新项
删除电子邮件
绑定,然后是 删除
使用 EWS 托管 API 删除项

使用 EWS 作为代理人获取、更新或删除电子邮件项目

可以使用 EWS 托管 API 获取、更新或删除电子邮件,其方式与不使用委托访问时执行这些操作的方式相同。 唯一的区别是服务对象适用于代理用户。 GetItem 请求中包含的项目 ID 唯一标识邮箱存储中邮箱所有者的“收件箱”文件夹中的项目。

表 3. 用于将电子邮件作为代理人处理的 EWS 操作

任务 EWS 操作 代码示例
获取电子邮件
GetItem
使用 EWS 获取项
更新电子邮件
GetItem,然后是 UpdateItem
使用 EWS 更新项
删除电子邮件
GetItem,然后是 DeleteItem
使用 EWS 删除项

另请参阅