通过在 Exchange 中使用 EWS 以代理身份访问联系人

了解如何使用 Exchange 中的 EWS 托管 API 或 EWS 作为代理人访问联系人。

可以使用 EWS 托管 API 或 EWS 授予用户对邮箱所有者的“联系人”文件夹的访问权限。 然后,代理可以代表邮箱所有者创建联系人,并根据邮箱所有者的“联系人”文件夹中的联系人检索、更新和删除联系人。

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

表 1. 用于以代理人身份访问联系人的 EWS 托管 API 方法和 EWS 操作

若要… 使用此 EWS 托管 API 方法… 使用此 EWS 操作…
创建联系人作为代理人
Item.Save where the FolderId 参数提供对邮箱所有者的“联系人”文件夹的显式访问权限
CreateItem,其中 邮箱 元素指定邮箱所有者的 EmailAddress
创建多个联系人作为代理人
ExchangeService.CreateItems,其中 FolderId 参数提供对邮箱所有者的“联系人”文件夹的显式访问权限
CreateItem,其中 邮箱 元素指定邮箱所有者的 EmailAddress
将联系人解析为代理人
ExchangeService.ResolveName,其中 FolderId 参数提供对邮箱所有者的“联系人”文件夹的显式访问权限
ResolveNames,其中 Mailbox 元素指定邮箱所有者的 EmailAddress
以代理人身份搜索或查找联系人
ExchangeService.FindItems,其中 FolderId 参数提供对邮箱所有者的“联系人”文件夹的显式访问
FindItem,其中 邮箱 元素指定邮箱所有者的 EmailAddress
以代理人身份获取联系人
Contact.Bind
GetItem
以代理人身份更新联系人
Contact.Bind 后跟 Contact.Update
GetItem,然后是 UpdateItem
删除作为代理人的联系人
Contact.Bind 后跟 Contact.Delete
GetItem,然后是 DeleteItem

注意

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

先决条件任务

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

使用 EWS 托管 API 创建联系人作为代理人

使用 EWS 托管 API,可以使用委托用户的服务对象为邮箱所有者创建联系人。 此示例演示了如何使用 保存 方法创建会议并向与会者发送会议请求。

此示例假定 服务 是代理的有效 ExchangeService 对象,并且已向代理授予邮箱所有者的“联系人”文件夹的相应权限。

 public static void DelegateAccessCreateContact(ExchangeService service)
{
    // Create the contact.
    Contact contact = new Contact(service);
    // Specify the name and how the contact should be filed.
    contact.GivenName = "Brian";
    contact.MiddleName = "David";
    contact.Surname = "Johnson";
    contact.FileAsMapping = FileAsMapping.SurnameCommaGivenName;
    // Specify the company name.
    contact.CompanyName = "Contoso";
    // Specify the business, home, and car phone numbers.
    contact.PhoneNumbers[PhoneNumberKey.BusinessPhone] = "425-555-0110";
    contact.PhoneNumbers[PhoneNumberKey.HomePhone] = "425-555-0120";
    contact.PhoneNumbers[PhoneNumberKey.CarPhone] = "425-555-0130";
    // Specify two email addresses.
    contact.EmailAddresses[EmailAddressKey.EmailAddress1] = 
        new EmailAddress("brian_1@contoso.com");
    contact.EmailAddresses[EmailAddressKey.EmailAddress2] = 
        new EmailAddress("brian_2@contoso.com");
    // Save the contact in the mailbox owner's Contacts folder.
    // This method call results in a CreateItem call to EWS. 
    // The contact identifier contains the context for the mailbox owner's 
    // Contact folder. Any additional actions take on this contact will 
    // be performed in the mailbox owner's mailbox. 
    contact.Save(new FolderId(WellKnownFolderName.Contacts, 
        "primary@contoso.com"));
    // Verify that the contact was created.
    // This method call results in a GetItem call to EWS
    // to load the display name property on the contact. 
    contact.Load(new PropertySet (ContactSchema.DisplayName));
    Console.WriteLine("\nContact created: " + contact.DisplayName + "\n");
}

请注意,保存项目时, Save 方法调用必须标识邮箱所有者的“联系人”文件夹。 如果未指定邮箱所有者的“联系人”文件夹,会议请求将保存到代理人的“联系人”文件夹,而不是邮箱所有者的“联系人”文件夹。 可以通过两种方式将邮箱所有者的“联系人”文件夹包含在 Save 方法调用中。 建议使用 WellKnownFolderName 和邮箱所有者的 SMTP 地址实例化 FolderId 对象的新实例。

contact.Save(new FolderId(WellKnownFolderName.Contacts, "primary@contoso.com"));

但是,也可以先 绑定到 “联系人”文件夹,然后在 Save 方法调用中使用文件夹的 ID。 但是,请注意,这将产生额外的 EWS 调用。

    // Identify the mailbox owner's SMTP address 
    // and bind to their Contacts folder.
    Mailbox primary = new Mailbox("primary@contoso.com"); 
    Folder primaryContacts = Folder.Bind(service, new FolderId(WellKnownFolderName.Contacts, primary)); 
…
    // Save the contact to the mailbox owner's Contacts folder.
    meeting.Save(primaryContacts.Id);

使用 EWS 创建联系人作为代理人

EWS 允许使用委托用户的服务对象为邮箱所有者创建联系人项目。 此示例演示如何使用 CreateItem 操作创建联系人。

这也是使用 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="contacts">
          <t:Mailbox>
            <t:EmailAddress>primary@contoso.com</t:EmailAddress>
          </t:Mailbox>
        </t:DistinguishedFolderId>
      </m:SavedItemFolderId>
      <m:Items>
        <t:Contact>
          <t:FileAsMapping>LastCommaFirst</t:FileAsMapping>
          <t:GivenName>Brian</t:GivenName>
          <t:MiddleName>David</t:MiddleName>
          <t:CompanyName>Contoso</t:CompanyName>
          <t:EmailAddresses>
            <t:Entry Key="EmailAddress1">brian_1@contoso.com</t:Entry>
            <t:Entry Key="EmailAddress2">brian_2@contoso.com</t:Entry>
          </t:EmailAddresses>
          <t:PhoneNumbers>
            <t:Entry Key="BusinessPhone">425-555-0110</t:Entry>
            <t:Entry Key="HomePhone">425-555-0120</t:Entry>
            <t:Entry Key="CarPhone">425-555-0130</t:Entry>
          </t:PhoneNumbers>
          <t:Surname>Johnson</t:Surname>
        </t:Contact>
      </m:Items>
    </m:CreateItem>
  </soap:Body>
</soap:Envelope>

服务器使用 CreateItemResponse 消息响应 CreateItem 请求,该消息包含 NoError的 ResponseCode 元素值,该值指示已成功创建联系人。 响应还包含新创建的联系人的项目 ID。

使用 EWS 托管 API 将联系人解析为代理人

若要根据可能不明确的姓名或术语查找联系人,必须使用包含 FolderId 参数的 ExchangeService.ResolveName 方法之一,以便可以指定邮箱所有者的“联系人”文件夹。

private static void DelegateAccessResolveContacts(ExchangeService service)
{
    // Create a list to store folders to search.
    List<FolderId> folders = new List<FolderId>();
   
    // Add the mailbox owner's folder to the list.
    folders.Add(new FolderId(WellKnownFolderName.Contacts, 
        "primary@contoso.com"));
    
    // Resolve the ambiguous name "Johnson".
    // This method call results in a ResolveNames call to EWS.
    NameResolutionCollection resolvedNames = service.ResolveName(
        "johnson", folders, ResolveNameSearchLocation.ContactsOnly, true);
    // Output the list of candidate email addresses and contact names.
    foreach (NameResolution nameRes in resolvedNames)
    {
        Console.WriteLine("Contact e-mail address: " + nameRes.Mailbox.Address);
        Console.WriteLine("Contact ID: " + nameRes.Mailbox.Id);
    }
}

ResolveNames 方法调用返回带有 ID 的响应后,可以使用 ID 和隐式访问获取、更新或删除联系人,并且无需指定邮箱所有者的 SMTP 地址。

使用 EWS 将联系人解析为代理人

EWS 使你能够使用委托用户的服务对象来解析邮箱所有者的“联系人”文件夹中的部分名称。 此示例演示如何使用 ResolveNames 操作在邮箱所有者的“联系人”文件夹中查找包含单词“johnson”的会议。

这也是使用 ResolveName 方法 解析联系人时 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:ResolveNames ReturnFullContactData="true"
                    SearchScope="Contacts">
      <m:ParentFolderIds>
        <t:DistinguishedFolderId Id="contacts">
          <t:Mailbox>
            <t:EmailAddress>primary@contoso.com</t:EmailAddress>
          </t:Mailbox>
        </t:DistinguishedFolderId>
      </m:ParentFolderIds>
      <m:UnresolvedEntry>johnson</m:UnresolvedEntry>
    </m:ResolveNames>
  </soap:Body>
</soap:Envelope>

服务器使用 ResolveNamesResponse 消息响应 ResolveNames 请求,该消息包含一个 ResponseCode 元素值 NoError,该值指示操作已成功完成,并且仅找到一个结果;如果找到多个结果,则返回 ErrorNameResolutionMultipleResults - 这是第三个代码示例中基于使用 EWS 托管 API 创建联系人作为委托的联系人的联系人所显示的内容。 响应还包含每个结果的 ItemId

为了便于阅读,已缩短 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:ResolveNamesResponse xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
                            xmlns:t="https://schemas.microsoft.com/exchange/services/2006/types">
      <m:ResponseMessages>
        <m:ResolveNamesResponseMessage ResponseClass="Warning">
          <m:MessageText>Multiple results were found.</m:MessageText>
          <m:ResponseCode>ErrorNameResolutionMultipleResults</m:ResponseCode>
          <m:DescriptiveLinkKey>0</m:DescriptiveLinkKey>
          <m:ResolutionSet TotalItemsInView="2"
                           IncludesLastItemInRange="true">
            <t:Resolution>
              <t:Mailbox>
                <t:Name>brian_1@contoso.com</t:Name>
                <t:EmailAddress>brian_1@contoso.com</t:EmailAddress>
                <t:RoutingType>SMTP</t:RoutingType>
                <t:MailboxType>Contact</t:MailboxType>
                <t:ItemId Id="iMihAAA="
                          ChangeKey="EQAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAABiPQo" />
              </t:Mailbox>
            </t:Resolution>
            <t:Resolution>
              <t:Mailbox>
                <t:Name>brian_2@contoso.com</t:Name>
                <t:EmailAddress>brian_2@contoso.com</t:EmailAddress>
                <t:RoutingType>SMTP</t:RoutingType>
                <t:MailboxType>Contact</t:MailboxType>
                <t:ItemId Id="iMihAAA="
                          ChangeKey="EQAAABYAAADOilbYa8KaT7ZgMoTz2P+hAAABiPQo" />
              </t:Mailbox>
            </t:Resolution>
          </m:ResolutionSet>
        </m:ResolveNamesResponseMessage>
      </m:ResponseMessages>
    </m:ResolveNamesResponse>
  </s:Body>
</s:Envelope>

现在,你已获得与不明确名称匹配的联系人的 ItemId,因此可以使用 EWS 通过 ItemId隐式访问获取、更新或删除联系人项目,而无需指定邮箱所有者的 SMTP 地址。

使用 EWS 托管 API 作为代理人获取、更新或删除联系人项目

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

表 2. 使用联系人作为代理人的 EWS 托管 API 方法

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

使用 EWS 作为代理人获取、更新或删除联系人项目

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

表 3. 用于以代理人身份处理联系人的 EWS 操作

任务 EWS 操作 示例
获取联系人
GetItem
使用 EWS 获取项
更新联系人
GetItem,然后是 UpdateItem
使用 EWS 更新项
删除联系人
GetItem,然后是 DeleteItem
使用 EWS 删除项

另请参阅