在 Exchange 中使用 EWS 批量处理联系人

了解如何使用 Exchange 中的 EWS 托管 API 或 EWS 在单个调用中创建、获取、更新和删除联系人批。

可以使用 EWS 托管 API 或 EWS 来处理成批的联系人,以减少客户端对 Exchange 服务器的调用数。 使用 EWS 托管 API 批量创建、获取、更新和删除联系人时,将使用 ExchangeService 对象方法,而使用单个联系人时,使用 Contact 对象方法。 如果使用的是 EWS,则使用相同的操作来处理单个联系人和一批联系人。

表 1. 用于处理批量联系人的 EWS 托管 API 方法和 EWS 操作

若要... 使用此 EWS 托管 API 方法 使用此 EWS 操作
批量创建联系人
ExchangeService.CreateItems
CreateItem
批量获取联系人
ExchangeService.BindToItemsExchangeService.LoadPropertiesForItems
GetItem
批量更新联系人
ExchangeService.UpdateItems
UpdateItem
批量删除联系人
ExchangeService.DeleteItems
DeleteItem

本文介绍如何使用 EWS 托管 API 或 EWS 完成联系人批处理的基本任务。

使用 EWS 托管 API 批量创建联系人

可以使用 EWS 托管 API CreateItems 方法批量创建联系人,如以下示例所示。 本示例在本地创建三个 Contact 对象,将每个联系人添加到集合,然后对联系人集合调用 CreateItems 方法。

public static Collection<ItemId> CreateContactsInBatch(ExchangeService service)
{
    // These are unsaved local instances of a Contact object.
    // Despite the required parameter of an ExchangeService object (service), no call
    // to an Exchange server is made when the objects are instantiated.
    // A call to the Exchange server is made when the service.CreateItems() method is called.
    Contact contact1 = new Contact(service);
    Contact contact2 = new Contact(service);
    Contact contact3 = new Contact(service);
    // Set the properties on the first contact.
    contact1.DisplayName = "Sadie Daniels";
    contact1.EmailAddresses[EmailAddressKey.EmailAddress1] = new EmailAddress("sadie@contoso.com");
    
    // Set the properties on the second contact.
    contact2.DisplayName = "Alfred Welker";
    contact2.EmailAddresses[EmailAddressKey.EmailAddress1] = new EmailAddress("alfred@contoso.com");
    // Set the properties on the third contact.
    contact3.DisplayName = "Hope Gross";
    contact3.EmailAddresses[EmailAddressKey.EmailAddress1] = new EmailAddress("hope@contoso.com");
    // Add the Contact objects to a collection.
    Collection<Contact> contactItems = new Collection<Contact>() { contact1, contact2, contact3 };
    // Create the batch of contacts on the server.
    // This method call results in an CreateItem call to EWS.
    ServiceResponseCollection<ServiceResponse> response = service.CreateItems(contactItems, WellKnownFolderName.Contacts, null, null);
    // Instantiate a collection of item IDs to populate from the values that are returned by the Exchange server.
    Collection<ItemId> itemIds = new Collection<ItemId>();
    // Collect the item IDs from the created contacts.
    foreach (Contact contact in contactItems)
    {
        try
        {
            itemIds.Add(contact.Id);
            Console.WriteLine("Contact '{0}' created successfully.", contact.DisplayName);
        }
        catch (Exception ex)
        {
            // Print out the exception and the last eight characters of the item ID.
            Console.WriteLine("Exception while creating contact {0}: {1}", contact.Id.ToString().Substring(144), ex.Message);
        }
    }
    // Determine whether the CreateItems method call completed successfully.
    if (response.OverallResult == ServiceResult.Success)
    {
            Console.WriteLine("All locally created contacts were successfully created in the Contacts folder.");
            Console.WriteLine("\r\n");
    }
   
    // If the method did not return success, print the result message for each contact.
    else
    {
        int counter = 1;
        foreach (ServiceResponse resp in response)
        {
            // Print out the result and the last eight characters of the item ID.
            Console.WriteLine("Result (contact {0}), id {1}: {2}", counter, itemIds[counter - 1].ToString().Substring(144), resp.Result);
            Console.WriteLine("Error Code: {0}", resp.ErrorCode);
            Console.WriteLine("ErrorMessage: {0}\r\n", resp.ErrorMessage);
            Console.WriteLine("\r\n");
            counter++;
        }
    }
    return itemIds;
}

使用 EWS 批量创建联系人

可以使用 CreateItem EWS 操作批量创建联系人,如以下代码示例所示。 这也是使用 EWS 托管 API 批量创建联系人时 EWS 托管 API 发送的 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>
        <m:SavedItemFolderId>
          <t:DistinguishedFolderId Id="contacts" />
        </m:SavedItemFolderId>
        <m:Items>
          <t:Contact>
            <t:DisplayName>Sadie Daniels</t:DisplayName>
            <t:EmailAddresses>
              <t:Entry Key="EmailAddress1">sadie@contoso.com</t:Entry>
            </t:EmailAddresses>
          </t:Contact>
          <t:Contact>
            <t:DisplayName>Alfred Welker</t:DisplayName>
            <t:EmailAddresses>
              <t:Entry Key="EmailAddress1">alfred@contoso.com</t:Entry>
            </t:EmailAddresses>
          </t:Contact>
          <t:Contact>
            <t:DisplayName>Hope Gross</t:DisplayName>
            <t:EmailAddresses>
              <t:Entry Key="EmailAddress1">hope@contoso.com</t:Entry>
            </t:EmailAddresses>
          </t:Contact>
        </m:Items>
      </m:CreateItem>
    </soap:Body>
  </soap:Envelope>

服务器使用 CreateItemResponse 消息响应 CreateItem 请求,其中包含每个新联系人的 ResponseCodeNoError,指示已成功创建和保存每个联系人。

使用 EWS 托管 API 批量获取联系人

可以使用 EWS 托管 API BindToItems 方法批量获取联系人,如以下示例所示。 此示例假定 service 是有效的 ExchangeService 对象,且用户已通过 Exchange 服务器的身份验证。

public static Collection<Contact> BatchGetContactItems(ExchangeService service, Collection<ItemId> itemIds)
        {
            // Create a property set that limits the properties returned by the Bind method to only those that are required.
            PropertySet propSet = new PropertySet(BasePropertySet.IdOnly, ContactSchema.DisplayName);
            // Get the items from the server.
            // This method call results in a GetItem call to EWS.
            ServiceResponseCollection<GetItemResponse> response = service.BindToItems(itemIds, propSet);
            // Instantiate a collection of Contact objects to populate from the values that are returned by the Exchange server.
            Collection<Contact> contactItems = new Collection<Contact>();
            foreach (GetItemResponse getItemResponse in response)
            {
                try
                {
                    Item item = getItemResponse.Item;
                    Contact contact = (Contact)item;
                    contactItems.Add(contact);
                    // Print out confirmation and the last eight characters of the item ID.
                    Console.WriteLine("Found item {0}.", contact.Id.ToString().Substring(144));
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception while getting a contact: {0}", ex.Message);
                }
            }
            // Check for success of the BindToItems method call.
            if (response.OverallResult == ServiceResult.Success)
            {
                Console.WriteLine("All contacts retrieved successfully.");
                Console.WriteLine("\r\n");
            }
            return contactItems;
        }

使用 EWS 批量获取联系人

可以使用 GetItem EWS 操作和以下示例中的代码批量获取联系人。 这也是使用 EWS 托管 API 分批获取联系人时 EWS 托管 API 发送的 XML 请求。 为了提高可读性, 已缩短 ItemId 属性。

<?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:GetItem>
        <m:ItemShape>
          <t:BaseShape>IdOnly</t:BaseShape>
          <t:AdditionalProperties>
            <t:FieldURI FieldURI="contacts:DisplayName" />
          </t:AdditionalProperties>
        </m:ItemShape>
        <m:ItemIds>
          <t:ItemId Id="ceJwVAAA=" ChangeKey="EQAAABYAAAD2WuN+TpqwSrNP9JCCMKC0AAFc51yS" />
          <t:ItemId Id="ceJwWAAA=" ChangeKey="EQAAABYAAAD2WuN+TpqwSrNP9JCCMKC0AAFc51yT" />
          <t:ItemId Id="ceJwXAAA=" ChangeKey="EQAAABYAAAD2WuN+TpqwSrNP9JCCMKC0AAFc51yU" />
        </m:ItemIds>
      </m:GetItem>
    </soap:Body>
  </soap:Envelope>

服务器使用 GetItemResponse 消息响应 GetItem 请求,其中包含每个请求的联系人的 ID 和显示名称。

使用 EWS 托管 API 批量更新联系人

可以使用 EWS 托管 API UpdateItems 方法批量更新联系人,如以下示例所示。 上一个示例创建联系人,但未指定他们为谁工作。 可以使用此示例中的代码一次性更新所有联系人以包含其公司名称。

此示例假定 service 是有效的 ExchangeService 对象,且用户已通过 Exchange 服务器的身份验证。

public static Collection<Contact> BatchUpdateContactItems(ExchangeService service, Collection<Contact> contactItems)
        {
            // Update the company name of each contact locally.
            foreach (Contact contact in contactItems)
            {
                // Update the company name of the contact.
                contact.CompanyName = "Contoso";
                // Print out confirmation with the last eight characters of the item ID and the contact company name.
                Console.WriteLine("Updated local contact {0} with the company name '{1}'.", contact.Id.ToString().Substring(144), contact.CompanyName);
            }
            
            // Send the item updates to the server.
            // This method call results in an UpdateItem call to EWS.
            ServiceResponseCollection<UpdateItemResponse> response = service.UpdateItems(contactItems, WellKnownFolderName.Contacts, ConflictResolutionMode.AutoResolve, null, null);
            // Verify the success of the UpdateItems method call.
            if (response.OverallResult == ServiceResult.Success)
            {
                Console.WriteLine("All contacts updated successfully.\r\n");
            }
            // If the method did not return success, print the result message for each contact.
            else
            {
                Console.WriteLine("All contacts were not successfully saved on the server.\r\n");
                int counter = 1;
                foreach (ServiceResponse resp in response)
                {
                    Console.WriteLine("Result for (contact {0}): {1}", counter, resp.Result);
                    Console.WriteLine("Error Code: {0}", resp.ErrorCode);
                    Console.WriteLine("ErrorMessage: {0}\r\n", resp.ErrorMessage);
                    counter++;
                }
            }
            return contactItems;
        }    

使用 EWS 批量更新联系人

可以使用 GetItem EWS 操作批量更新联系人,如以下代码示例所示。 这也是使用 EWS 托管 API 批量更新联系人时 EWS 托管 API 发送的 XML 请求。 为了提高可读性, 已缩短 ItemId 属性。

<?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:UpdateItem ConflictResolution="AutoResolve">
        <m:SavedItemFolderId>
          <t:DistinguishedFolderId Id="contacts" />
        </m:SavedItemFolderId>
        <m:ItemChanges>
          <t:ItemChange>
            <t:ItemId Id="ceJwVAAA=" ChangeKey="EQAAABYAAAD2WuN+TpqwSrNP9JCCMKC0AAFc51yS" />
            <t:Updates>
              <t:SetItemField>
                <t:FieldURI FieldURI="contacts:CompanyName" />
                <t:Contact>
                  <t:CompanyName>Contoso</t:CompanyName>
                </t:Contact>
              </t:SetItemField>
            </t:Updates>
          </t:ItemChange>
          <t:ItemChange>
            <t:ItemId Id="ceJwWAAA=" ChangeKey="EQAAABYAAAD2WuN+TpqwSrNP9JCCMKC0AAFc51yT" />
            <t:Updates>
              <t:SetItemField>
                <t:FieldURI FieldURI="contacts:CompanyName" />
                <t:Contact>
                  <t:CompanyName>Contoso</t:CompanyName>
                </t:Contact>
              </t:SetItemField>
            </t:Updates>
          </t:ItemChange>
          <t:ItemChange>
            <t:ItemId Id="ceJwXAAA=" ChangeKey="EQAAABYAAAD2WuN+TpqwSrNP9JCCMKC0AAFc51yU" />
            <t:Updates>
              <t:SetItemField>
                <t:FieldURI FieldURI="contacts:CompanyName" />
                <t:Contact>
                  <t:CompanyName>Contoso</t:CompanyName>
                </t:Contact>
              </t:SetItemField>
            </t:Updates>
          </t:ItemChange>
        </m:ItemChanges>
      </m:UpdateItem>
    </soap:Body>
  </soap:Envelope>

服务器使用 UpdateItemResponse 消息响应 UpdateItem 请求,该消息包含 NoErrorResponseCode 值,该值指示每个更新已成功保存在服务器上。 任何冲突都报告在 ConflictResult 元素中。

使用 EWS 托管 API 批量删除联系人

可以使用 DeleteItems EWS 托管 API 方法批量删除联系人,如以下示例所示。 此示例假定 service 是有效的 ExchangeService 对象,且用户已通过 Exchange 服务器的身份验证。

public static void BatchDeleteContactItems(ExchangeService service, Collection<ItemId> itemIds)
        {
            // Delete the batch of contact objects.
            // This method call results in an DeleteItem call to EWS.
            ServiceResponseCollection<ServiceResponse> response = service.DeleteItems(itemIds, DeleteMode.SoftDelete, null, AffectedTaskOccurrence.AllOccurrences);
            // Check for success of the DeleteItems method call.
            // DeleteItems returns success even if it does not find all the item IDs.
            if (response.OverallResult == ServiceResult.Success)
            {
                Console.WriteLine("Contacts deleted successfully.\r\n");
            }
            // If the method did not return success, print a message.
            else
            {
                Console.WriteLine("Not all contacts deleted successfully.\r\n");
            }
        }

使用 EWS 批量删除联系人

可以使用 DeleteItem EWS 操作批量删除联系人,如以下代码示例所示。 这也是使用 EWS 托管 API 批量删除联系人时 EWS 托管 API 发送的 XML 请求。 为了提高可读性, 已缩短 ItemId 属性。

<?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:DeleteItem DeleteType="SoftDelete" AffectedTaskOccurrences="AllOccurrences">
        <m:ItemIds>
          <t:ItemId Id="ceJwYAAA=" ChangeKey="EQAAABYAAAD2WuN+TpqwSrNP9JCCMKC0AAFc51yY" />
          <t:ItemId Id="ceJwZAAA=" ChangeKey="EQAAABYAAAD2WuN+TpqwSrNP9JCCMKC0AAFc51yZ" />
          <t:ItemId Id="ceJwaAAA=" ChangeKey="EQAAABYAAAD2WuN+TpqwSrNP9JCCMKC0AAFc51ya" />
        </m:ItemIds>
      </m:DeleteItem>
    </soap:Body>
  </soap:Envelope>

服务器使用 DeleteItemResponse 消息响应 DeleteItem 请求,该消息包含已删除的每个项的 ResponseCodeNoError。 请注意,如果找不到项 ID,操作也会返回成功。

验证批处理是否成功完成

当批处理请求中的一个或多个联系人无法按请求进行处理时,将为每个失败的联系人返回错误,并按预期处理批处理中的其余联系人。 如果项目已被删除,因此无法检索或更新,或者该项目已移动到其他文件夹,因此具有新的项目 ID,并且无法使用发送的项目 ID 进行修改,则批处理可能会失败。 本部分中的信息演示如何获取有关联系人批处理失败的错误详细信息。

若要使用 EWS 托管 API 验证批处理是否成功,可以检查 ServiceResponseCollectionOverallResult 属性是否等于 ServiceResult.Success。 如果是这样,则已成功处理所有联系人。 如果 OverallResult 不等于 ServiceResult.Success,则一个或多个联系人未成功处理。 ServiceResponseCollection 中返回的每个对象包含以下属性:

这些属性包含有关无法按请求处理联系人的原因的信息。 本文中的示例输出每个失败联系人 的结果ErrorCodeErrorMessage 。 可以使用这些结果来调查问题。

对于 EWS,若要验证批处理过程是否成功,请检查正在处理的每个项的 ResponseClass 属性。 下面是 ResponseMessageType 的基本结构,这是派生所有响应消息的基类型。

<ResponseMessage ResponseClass="Success | Warning | Error">
            <MessageText/>
            <ResponseCode/>
            <DescriptiveLinkKey/>
            <MessageXml/>
</ResponseMessage>

如果已成功处理联系人,则 ResponseClass 属性设置为 Success ;如果未成功处理联系人,则设置为 “错误 ”。 对于联系人,在批处理期间不会遇到 警告 。 如果 ResponseClassSuccess,则后面的 ResponseCode 元素也始终设置为 NoError。 如果 ResponseClassError,则需要检查 MessageTextResponseCodeMessageXml 元素的值,以确定导致问题的原因。 描述性LinkKey 当前未使用。

另请参阅