Exchange において EWS を使用してバッチ処理で連絡先を処理する

Exchange で EWS マネージ API または EWS を使用して、1 回の呼び出しで連絡先の作成、取得、更新、削除をバッチ処理する方法について説明します。

EWS マネージ API または EWS を使用すると、連絡先のバッチ操作を行い、クライアントが Exchange サーバーを呼び出す回数を減らせます。 EWS マネージ API を使用して連絡先の作成、取得、更新、削除のバッチ操作を行う場合、ExchangeService オブジェクト メソッドを使用します。1 つの連絡先を対象とする場合には Contact オブジェクト メソッドを使用します。 EWS を使用する場合は、同じ操作を使用して 1 つの連絡先の処理とバッチ処理のどちらも行えます。

表 1. 連絡先をバッチ処理するための EWS マネージ API メソッドと EWS 操作

目的 使用する EWS マネージ API メソッド 使用する EWS 操作
バッチ処理による連絡先の作成
ExchangeService.CreateItems
CreateItem
バッチ処理による連絡先の取得
ExchangeService.BindToItems または ExchangeService.LoadPropertiesForItems
GetItem
バッチ処理による連絡先の更新
ExchangeService.UpdateItems
UpdateItem
バッチ処理による連絡先の削除
ExchangeService.DeleteItems
DeleteItem

この記事では、EWS マネージ API または EWS を使用して連絡先のバッチ処理を行うための基本的なタスクの実行方法について説明します。

EWS マネージ API を使用してバッチ処理で連絡先を作成する

次の例に示されているように、EWS マネージ API の CreateItems メソッドを使用すると、バッチ処理で連絡先を作成できます。 この例では、3 つの 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="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>
        <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>

サーバーは、CreateItem 要求に CreateItemResponse メッセージで応答します。このメッセージには、それぞれの新しい連絡先が正常に作成および保存されたことを示す、NoErrorResponseCode 値が含まれます。

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="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: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>

サーバーは GetItem 要求に GetItemResponse メッセージで応答します。このメッセージには、要求された連絡先の各 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="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: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>

サーバーは UpdateItem 要求に応答し、ResponseCodeNoError を含む UpdateItemResponse メッセージが返されます。これは、各更新プログラムがサーバーに正常に保存されたことを示します。 競合はすべて ConflictResult 要素で報告されます。

EWS マネージ API を使用してバッチ処理で連絡先を削除する

次の例に示されているように、EWS マネージ API の DeleteItems メソッドを使用すると、バッチ処理で連絡先を削除できます。 この例では、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="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: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>

サーバーは、DeleteItem 要求に DeleteItemResponse メッセージで応答します。このメッセージには、削除された各アイテムの NoErrorResponseCode 値が含まれます。 項目 ID が見つからなかった場合も、操作によって成功が返されることに注意してください。

バッチ処理が正常に完了したことを確認する

バッチ処理された要求の 1 つ以上の連絡先を要求どおりに処理できない場合は、失敗した連絡先ごとにエラーが返され、バッチ内の残りの連絡先は期待どおりに処理されます。 バッチ処理でエラーが発生するのは、アイテムが削除された場合、そのため、アイテムを取得または更新できない場合、またはアイテムが別のフォルダーに移動した場合、そのため新しいアイテム ID を持ち、送信されたアイテム ID で変更できない場合です。 このセクションの情報では、連絡先のバッチ処理でのエラーに関するエラーの詳細を取得する方法を示します。

EWS マネージ API を使用してバッチ処理が成功したかどうかは、ServiceResponseCollectionOverallResult プロパティが ServiceResult.Success と等しいことを調べることで確認できます。 等しい場合は、すべての連絡先が正常に処理されました。 OverallResultServiceResult.Success と等しくない場合は、1 つ以上の連絡先が正常に処理されませんでした。 ServiceResponseCollection で返される各オブジェクトには、次のプロパティが含まれます。

これらのプロパティには、連絡先を要求どおりに処理できなかった原因についての情報が含まれます。 この資料の例では、エラーが生じた各連絡先の ResultErrorCodeErrorMessage が出力されます。 これらの結果を使用して問題を調査できます。

EWS でバッチ処理が成功したことを確認するには、各処理対象アイテムの ResponseClass 属性を調べます。 すべての応答メッセージの派生元となる基本タイプの ResponseMessageType の基本構造を次に示します。

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

ResponseClass 属性は、連絡先が正常に処理された場合には Success に設定され、正常に処理されなかった場合には Error に設定されます。 連絡先の場合には、バッチ処理中に Warning が示されることはありません。 ResponseClassSuccess の場合、それに続く ResponseCode 要素は必ず NoError に設定されます。 ResponseClassError の場合、MessageTextResponseCodeMessageXml の各要素の値を確認し、問題の原因を特定する必要があります。 DescriptiveLinkKey は現在使用されていません。

関連項目