Web API を使用してバッチ操作を実行する

バッチ操作を使用して複数の操作を 1 つの HTTP 要求にグループ化することができます。 これらの操作は、指定された順序で順番に実行されます。 応答の順序は、バッチ操作での要求の順序と一致します。

$batch 要求の送信形式は、OData 仕様のこのセクションで定義されています: 11.7 バッチ要求。 この記事の内容は、仕様の要件を要約して Dataverse に固有の情報と例を提供します。

バッチ要求を使用する場合

バッチ要求は、一緒に使用できる 2 つの機能を提供します:

  • 1 回の HTTP 要求で複数の操作の要求を送信することができます。

    • バッチ要求には最大 1000 個の別々要求を含めることができますが、他のバッチ要求を含めることはできません。
    • Web API $batch 要求は、SDK for .NET で利用可能な ExecuteMultiple メッセージと同等です。 詳細: .NET 用 SDK を使用して複数の要求を実行する
  • 操作の要求をまとめてグループ化し、変更セット を使用して 1 つのトランザクションとして含めることができます。

    • すべての操作がグループとして成功または失敗することを保証する方法で、一連の関連レコードを作成、更新、または削除することができます。
    • 変更セットを使用した Web API $batch 要求は、SDK for .NET で利用可能な ExecuteTransaction メッセージと同等です。 詳細: 単一のデータベース トランザクションでメッセージを実行する

    注意

    バッチ要求を使用するよりも簡単に、関連付けられたエンティティを 1 回の操作で作成できることに注意してください。 詳細: 1 回の操作で関連するテーブル行を作成する

バッチ要求は、URL の長さが URL の最大許容長 を超える可能性がある GET 要求を送信するためにも使用されることがあります。 バッチ リクエストが使用されるのは、リクエストのURLがメッセージ本文に含まれており、最大64 KB (65,536文字) のURLが許可されるためです。 FetchXml を使用して複雑なクエリを送信すると、URL が長くなる可能性があります。 詳細: バッチ要求内で FetchXML を使用する

Web API を使用して実行できる他の操作と比較して、バッチ要求は作成が難しくなります。 raw 要求と応答の本文は、基本的に、特定の要件に一致する必要があるテキスト ドキュメントです。 応答でこのデータにアクセスするには、応答内のテキストを解析するか、応答内のデータにアクセスするためのヘルパー ライブラリを検索する必要があります。 .NET ヘルパー メソッド を参照してください。

バッチ要求

POST 要求を使用して、複数の要求が含まれているバッチ操作を送信します。

バッチを含む POST 要求には、このパターンを使用してバッチの識別子を含むように boundary が設定された、multipart/mixed に設定された値を持つ Content-Type ヘッダーが必要です。

POST [Organization Uri]/api/data/v9.2/$batch HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
Content-Type: multipart/mixed; boundary="batch_<unique identifier>"

一意識別子は GUID である必要はありませんが、一意である必要があります。

バッチ内の各項目の前に、次の例ような Content-Type および Content-Transfer-Encoding ヘッダーを持つバッチ識別子が必要です。

--batch_<unique identifier>
Content-Type: application/http
Content-Transfer-Encoding: binary

重要

Content-Type ヘッダーで送信されたバッチ識別子と一致するバッチ識別子を持つペイロード項目のみが実行されます。 ペイロード アイテムが Content-Type バッチ識別子を使用しない場合、バッチ リクエストはペイロード アイテムを実行せずに成功します。

その要求の動作を制御するには、バッチで各項目に他の HTTP ヘッダー を含める必要があります。 $batch 操作に適用されるヘッダーは、各アイテムには適用されません。 たとえば、GET 要求を含めて 注釈を要求 する場合は、各アイテムに適切な Prefer: odata.include-annotations="*" ヘッダーを追加する必要があります。

バッチ要求の最後には、次の例のように、終端のインジケーターを含める必要があります:

--batch_<unique identifier>--

注意

HTTP プロトコルでは、$batch リクエスト ペイロードのすべての行末が CRLF である必要があります。 他の行末では逆シリアル化エラーが発生する可能性があります。 例: System.ArgumentException: Stream was not readable.。 CRLF を使用できない場合は、リクエスト ペイロードの最後に 2 つの非 CRLF 行末を追加して、ほとんどの逆シリアル化エラーを解決できます。

次の例は、変更セットを使用しないバッチ要求です。 この例では:

  • accountid00000000-0000-0000-0000-000000000001 に等しいアカウントに関連付けられた 3 つのタスク レコードを作成します。
  • アカウントに関連付けられたタスク レコードを取得します。

要求:

POST [Organization Uri]/api/data/v9.2/$batch HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
Content-Type: multipart/mixed; boundary="batch_80dd1615-2a10-428a-bb6f-0e559792721f"

--batch_80dd1615-2a10-428a-bb6f-0e559792721f
Content-Type: application/http
Content-Transfer-Encoding: binary

POST /api/data/v9.2/tasks HTTP/1.1
Content-Type: application/json; type=entry

{
  "subject": "Task 1 in batch",
  "regardingobjectid_account_task@odata.bind": "accounts(00000000-0000-0000-0000-000000000001)"
}
--batch_80dd1615-2a10-428a-bb6f-0e559792721f
Content-Type: application/http
Content-Transfer-Encoding: binary

POST /api/data/v9.2/tasks HTTP/1.1
Content-Type: application/json; type=entry

{
  "subject": "Task 2 in batch",
  "regardingobjectid_account_task@odata.bind": "accounts(00000000-0000-0000-0000-000000000001)"
}
--batch_80dd1615-2a10-428a-bb6f-0e559792721f
Content-Type: application/http
Content-Transfer-Encoding: binary

POST /api/data/v9.2/tasks HTTP/1.1
Content-Type: application/json; type=entry

{
  "subject": "Task 3 in batch",
  "regardingobjectid_account_task@odata.bind": "accounts(00000000-0000-0000-0000-000000000001)"
}
--batch_80dd1615-2a10-428a-bb6f-0e559792721f
Content-Type: application/http
Content-Transfer-Encoding: binary

GET /api/data/v9.2/accounts(00000000-0000-0000-0000-000000000001)/Account_Tasks?$select=subject HTTP/1.1


--batch_80dd1615-2a10-428a-bb6f-0e559792721f--

バッチ応答

成功すると、バッチ応答はHTTPステータス 200 OK を返し、応答内の各項目はバッチ リクエスト値と同じではない Guid 一意の識別子の値で区切られます。

--batchresponse_<unique identifier>
Content-Type: application/http
Content-Transfer-Encoding: binary

バッチ応答の最後には、次例のように、終端のインジケーターが含まれます。

--batchresponse_<unique identifier>--

次の例は、前のバッチ リクエストの例に対する応答です。

応答:

HTTP/1.1 200 OK
OData-Version: 4.0

--batchresponse_01346794-f2e2-4d45-8cc2-f97e09fe8916
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 204 No Content
OData-Version: 4.0
Location: [Organization Uri]/api/data/v9.2/tasks(d31ba648-c592-ed11-aad1-000d3a993550)
OData-EntityId: [Organization Uri]/api/data/v9.2/tasks(d31ba648-c592-ed11-aad1-000d3a993550)


--batchresponse_01346794-f2e2-4d45-8cc2-f97e09fe8916
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 204 No Content
OData-Version: 4.0
Location: [Organization Uri]/api/data/v9.2/tasks(d41ba648-c592-ed11-aad1-000d3a993550)
OData-EntityId: [Organization Uri]/api/data/v9.2/tasks(d41ba648-c592-ed11-aad1-000d3a993550)


--batchresponse_01346794-f2e2-4d45-8cc2-f97e09fe8916
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 204 No Content
OData-Version: 4.0
Location: [Organization Uri]/api/data/v9.2/tasks(d51ba648-c592-ed11-aad1-000d3a993550)
OData-EntityId: [Organization Uri]/api/data/v9.2/tasks(d51ba648-c592-ed11-aad1-000d3a993550)


--batchresponse_01346794-f2e2-4d45-8cc2-f97e09fe8916
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true
OData-Version: 4.0

{
  "@odata.context": "[Organization Uri]/api/data/v9.2/$metadata#tasks(subject)",
  "value": [
    {
      "@odata.etag": "W/\"77180907\"",
      "subject": "Task 1 in batch",
      "activityid": "d31ba648-c592-ed11-aad1-000d3a993550"
    },
    {
      "@odata.etag": "W/\"77180910\"",
      "subject": "Task 2 in batch",
      "activityid": "d41ba648-c592-ed11-aad1-000d3a993550"
    },
    {
      "@odata.etag": "W/\"77180913\"",
      "subject": "Task 3 in batch",
      "activityid": "d51ba648-c592-ed11-aad1-000d3a993550"
    }
  ]
}
--batchresponse_01346794-f2e2-4d45-8cc2-f97e09fe8916--

変更セット

バッチ要求には、個々の要求に加えて変更セットを含めることができます。 複数の操作が変更セットに含まれている場合、すべての操作は アトミック と見なされます。 アトミック操作とは、どれかの操作が失敗すると、すでに完了した操作がロールバックされます。

注意

GET 要求は変更セット内では許可されません。 GET 操作はデータを変更してはならないため、変更セット内に属しません。

バッチ要求のように、変更セットには、このパターンを使用して変更セットの識別子を含むように boundary が設定された、multipart/mixed に値が設定された Content-Type ヘッダーが必要です。

Content-Type: multipart/mixed; boundary="changeset_<unique identifier>"

一意識別子は GUID である必要はありませんが、一意である必要があります。 変更セット内の各項目の前に、次例のような Content-Type and Content-Transfer-Encoding ヘッダーを持つ変更セット識別子が必要です。

--changeset_<unique identifier>
Content-Type: application/http
Content-Transfer-Encoding: binary

また、変更セットには、一意の値を持つ Content-ID ヘッダーを含めることもできます。 この値は、接頭辞 $ が付くと、その操作で作成された任意のエンティティの URI を格納する変数を表します。 たとえば、値 1 を設定すると、後から変更セット内で $1 を使用してそのエンティティを参照できます。 詳細: 運用における参照 URI

変更セットの最後には、次の例のように、終端のインジケーターを含める必要があります。

--changeset_<unique identifier>--

次の例は、変更セットの使用方法を示しています:

  • accountid00000000-0000-0000-0000-000000000001 のアカウントに関連付けられた 3 つのタスクの作成をグループ化します。
  • changeset の外部で GET 要求を使用して作成されたアカウントを取得します。

要求:

POST [Organization Uri]/api/data/v9.2/$batch HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
Content-Type: multipart/mixed; boundary="batch_22975cad-7f57-410d-be15-6363209367ea"

--batch_22975cad-7f57-410d-be15-6363209367ea
Content-Type: multipart/mixed; boundary="changeset_246e6bfe-89a4-4c77-b293-7a433f082e8a"

--changeset_246e6bfe-89a4-4c77-b293-7a433f082e8a
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1

POST /api/data/v9.2/tasks HTTP/1.1
Content-Type: application/json; type=entry

{
  "subject": "Task 1 in batch",
  "regardingobjectid_account_task@odata.bind": "accounts(00000000-0000-0000-0000-000000000001)"
}
--changeset_246e6bfe-89a4-4c77-b293-7a433f082e8a
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 2

POST /api/data/v9.2/tasks HTTP/1.1
Content-Type: application/json; type=entry

{
  "subject": "Task 2 in batch",
  "regardingobjectid_account_task@odata.bind": "accounts(00000000-0000-0000-0000-000000000001)"
}
--changeset_246e6bfe-89a4-4c77-b293-7a433f082e8a
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 3

POST /api/data/v9.2/tasks HTTP/1.1
Content-Type: application/json; type=entry

{
  "subject": "Task 3 in batch",
  "regardingobjectid_account_task@odata.bind": "accounts(00000000-0000-0000-0000-000000000001)"
}
--changeset_246e6bfe-89a4-4c77-b293-7a433f082e8a--

--batch_22975cad-7f57-410d-be15-6363209367ea
Content-Type: application/http
Content-Transfer-Encoding: binary

GET /api/data/v9.2/accounts(00000000-0000-0000-0000-000000000001)/Account_Tasks?$select=subject HTTP/1.1


--batch_22975cad-7f57-410d-be15-6363209367ea--

応答:

HTTP/1.1 200 OK
OData-Version: 4.0

--batchresponse_f27ef42d-51b0-4685-bac9-f468f844de2f
Content-Type: multipart/mixed; boundary=changesetresponse_64cc3fff-023a-45b0-b29d-df21583ffa15

--changesetresponse_64cc3fff-023a-45b0-b29d-df21583ffa15
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1

HTTP/1.1 204 No Content
OData-Version: 4.0
Location: [Organization Uri]/api/data/v9.2/tasks(e73ffc82-e292-ed11-aad1-000d3a9933c9)
OData-EntityId: [Organization Uri]/api/data/v9.2/tasks(e73ffc82-e292-ed11-aad1-000d3a9933c9)


--changesetresponse_64cc3fff-023a-45b0-b29d-df21583ffa15
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 2

HTTP/1.1 204 No Content
OData-Version: 4.0
Location: [Organization Uri]/api/data/v9.2/tasks(e83ffc82-e292-ed11-aad1-000d3a9933c9)
OData-EntityId: [Organization Uri]/api/data/v9.2/tasks(e83ffc82-e292-ed11-aad1-000d3a9933c9)


--changesetresponse_64cc3fff-023a-45b0-b29d-df21583ffa15
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 3

HTTP/1.1 204 No Content
OData-Version: 4.0
Location: [Organization Uri]/api/data/v9.2/tasks(e93ffc82-e292-ed11-aad1-000d3a9933c9)
OData-EntityId: [Organization Uri]/api/data/v9.2/tasks(e93ffc82-e292-ed11-aad1-000d3a9933c9)


--changesetresponse_64cc3fff-023a-45b0-b29d-df21583ffa15--
--batchresponse_f27ef42d-51b0-4685-bac9-f468f844de2f
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 200 OK
Content-Type: application/json; odata.metadata=minimal; odata.streaming=true
OData-Version: 4.0

{
  "@odata.context": "[Organization Uri]/api/data/v9.2/$metadata#tasks(subject)",
  "value": [
    {
      "@odata.etag": "W/\"77181173\"",
      "subject": "Task 1 in batch",
      "activityid": "e73ffc82-e292-ed11-aad1-000d3a9933c9"
    },
    {
      "@odata.etag": "W/\"77181176\"",
      "subject": "Task 2 in batch",
      "activityid": "e83ffc82-e292-ed11-aad1-000d3a9933c9"
    },
    {
      "@odata.etag": "W/\"77181179\"",
      "subject": "Task 3 in batch",
      "activityid": "e93ffc82-e292-ed11-aad1-000d3a9933c9"
    }
  ]
}
--batchresponse_f27ef42d-51b0-4685-bac9-f468f844de2f--

運用における参照URI

changeset 内では $1 $2 などの $parameter を使用すると、同じ changeset 内で以前に作成された新規エンティティー用に戻された URI を参照します。 詳細については、OData v4.0 の仕様を参照してください: 11.7.3.1 変更セット内の要求の参照

このセクションでは、 $parameter をバッチ操作の要求本体で使用してURIを参照する方法について、さまざまな例を示します。

要求本体のURI参照

以下の例では、2つのURI参照を1回の操作で使用する方法を示しています。

要求:

POST [Organization URI]/api/data/v9.2/$batch HTTP/1.1
Content-Type:  multipart/mixed;boundary=batch_AAA123
Accept:  application/json
OData-MaxVersion:  4.0
OData-Version:  4.0

--batch_AAA123
Content-Type: multipart/mixed; boundary=changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab

--changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1

POST [Organization URI]/api/data/v9.2/leads HTTP/1.1
Content-Type: application/json

{
    "firstname":"first name",
    "lastname":"last name"
}

--changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 2

POST [Organization URI]/api/data/v9.2/contacts HTTP/1.1
Content-Type: application/json

{"firstname":"first name"}

--changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 3

POST [Organization URI]/api/data/v9.2/accounts HTTP/1.1
Content-Type: application/json

{
    "name":"IcM Account",
    "originatingleadid@odata.bind":"$1",
    "primarycontactid@odata.bind":"$2"
}

--changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab--
--batch_AAA123--

応答:

HTTP/1.1 200 OK
OData-Version: 4.0

--batchresponse_3cace264-86ea-40fe-83d3-954b336c0f4a
Content-Type: multipart/mixed; boundary=changesetresponse_1a5db8a1-ec98-42c4-81f6-6bc6adcfa4bc

--changesetresponse_1a5db8a1-ec98-42c4-81f6-6bc6adcfa4bc
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1

HTTP/1.1 204 No Content
OData-Version: 4.0
Location: [Organization URI]/api/data/v9.2/leads(425195a4-7a75-e911-a97a-000d3a34a1bd)
OData-EntityId: [Organization URI]/api/data/v9.2/leads(425195a4-7a75-e911-a97a-000d3a34a1bd)

--changesetresponse_1a5db8a1-ec98-42c4-81f6-6bc6adcfa4bc
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 2

HTTP/1.1 204 No Content
OData-Version: 4.0
Location: [Organization URI]/api/data/v9.2/contacts(495195a4-7a75-e911-a97a-000d3a34a1bd)
OData-EntityId: [Organization URI]/api/data/v9.2/contacts(495195a4-7a75-e911-a97a-000d3a34a1bd)

--changesetresponse_1a5db8a1-ec98-42c4-81f6-6bc6adcfa4bc
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 3

HTTP/1.1 204 No Content
OData-Version: 4.0
Location: [Organization URI]/api/data/v9.2/accounts(4f5195a4-7a75-e911-a97a-000d3a34a1bd)
OData-EntityId: [Organization URI]/api/data/v9.2/accounts(4f5195a4-7a75-e911-a97a-000d3a34a1bd)

--changesetresponse_1a5db8a1-ec98-42c4-81f6-6bc6adcfa4bc--
--batchresponse_3cace264-86ea-40fe-83d3-954b336c0f4a--

要求URLのURI参照

以下の例は、この後に続く要求URLで $1 を使用してURIを参照する方法を示しています。

要求:

POST [Organization URI]/api/data/v9.2/$batch HTTP/1.1
Content-Type:  multipart/mixed;boundary=batch_AAA123
Accept:  application/json
OData-MaxVersion:  4.0
OData-Version:  4.0

--batch_AAA123
Content-Type: multipart/mixed; boundary=changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab

--changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1

POST [Organization URI]/api/data/v9.2/contacts HTTP/1.1
Content-Type: application/json

{
  "firstname":"First Name",
  "lastname":"Last name"
}

--changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab
Content-Transfer-Encoding: binary
Content-Type: application/http
Content-ID: 2

PUT $1/lastname HTTP/1.1
Content-Type: application/json

{
  "value":"BBBBB"
}

--changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab--
--batch_AAA123--

応答:

HTTP/1.1 200 OK
OData-Version: 4.0

--batchresponse_2cb48f48-39a8-41ea-aa52-132fa8ab3c2d
Content-Type: multipart/mixed; boundary=changesetresponse_d7528170-3ef3-41bd-be8e-eac971a8d9d4

--changesetresponse_d7528170-3ef3-41bd-be8e-eac971a8d9d4
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1

HTTP/1.1 204 No Content
OData-Version: 4.0
Location:[Organization URI]/api/data/v9.2/contacts(f8ea5d2c-8c75-e911-a97a-000d3a34a1bd)
OData-EntityId:[Organization URI]/api/data/v9.2/contacts(f8ea5d2c-8c75-e911-a97a-000d3a34a1bd)


--changesetresponse_d7528170-3ef3-41bd-be8e-eac971a8d9d4
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 2

HTTP/1.1 204 No Content
OData-Version: 4.0


--changesetresponse_d7528170-3ef3-41bd-be8e-eac971a8d9d4--
--batchresponse_2cb48f48-39a8-41ea-aa52-132fa8ab3c2d--

URLの参照URIと @odata.idを使用する要求本体

以下の例では、取引先担当者 エンティティー レコードを、取引先企業 エンティティー レコードにリンクする方法を示しています。 取引先企業 エンティティー レコードのURIは $1 として参照され、取引先担当者 エンティティー レコードのURIは $2として参照されます。

要求:

POST [Organization URI]/api/data/v9.2/$batch HTTP/1.1
Content-Type:multipart/mixed;boundary=batch_AAA123
Accept:application/json
OData-MaxVersion:4.0
OData-Version:4.0

--batch_AAA123
Content-Type: multipart/mixed; boundary=changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab

--changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab
Content-Type:application/http
Content-Transfer-Encoding:binary
Content-ID:1

POST [Organization URI]/api/data/v9.2/accounts HTTP/1.1
Content-Type: application/json

{ "name":"Account Name"}

--changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab
Content-Type:application/http
Content-Transfer-Encoding:binary
Content-ID:2

POST [Organization URI]/api/data/v9.2/contacts HTTP/1.1
Content-Type:application/json

{ "firstname":"Contact first name"}

--changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab
Content-Type:application/http
Content-Transfer-Encoding:binary
Content-ID:3

PUT $1/primarycontactid/$ref HTTP/1.1
Content-Type:application/json

{"@odata.id":"$2"}

--changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab--
--batch_AAA123--

応答:

HTTP/1.1 200 OK
OData-Version: 4.0

--batchresponse_0740a25c-d8e1-41a5-9202-1b50a297864c
Content-Type: multipart/mixed; boundary=changesetresponse_19ca0da8-d8bb-4273-a3f7-fe0d0fadfe5f

--changesetresponse_19ca0da8-d8bb-4273-a3f7-fe0d0fadfe5f
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1

HTTP/1.1 204 No Content
OData-Version: 4.0
Location:[Organization URI]/api/data/v9.2/accounts(3dcf8c02-8c75-e911-a97a-000d3a34a1bd)
OData-EntityId:[Organization URI]/api/data/v9.2/accounts(3dcf8c02-8c75-e911-a97a-000d3a34a1bd)

--changesetresponse_19ca0da8-d8bb-4273-a3f7-fe0d0fadfe5f
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 2

HTTP/1.1 204 No Content
OData-Version: 4.0
Location:[Organization URI]/api/data/v9.2/contacts(43cf8c02-8c75-e911-a97a-000d3a34a1bd)
OData-EntityId:[Organization URI]/api/data/v9.2/contacts(43cf8c02-8c75-e911-a97a-000d3a34a1bd)

--changesetresponse_19ca0da8-d8bb-4273-a3f7-fe0d0fadfe5f
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 3

HTTP/1.1 204 No Content
OData-Version: 4.0

--changesetresponse_19ca0da8-d8bb-4273-a3f7-fe0d0fadfe5f--
--batchresponse_0740a25c-d8e1-41a5-9202-1b50a297864c--

URL とナビゲーション プロパティの参照URI

次の例は、取引先担当者レコードの組織URIを使用し、 primarycontactid の単一値ナビゲーション プロパティを使用して取引先企業レコードにリンクする方法を示しています。 PATCH 要求では、取引先企業エンティティー レコードのURIは $1 として参照され、取引先担当者エンティティー レコードのURIは $2 として参照されます。

要求:

POST [Organization URI]/api/data/v9.2/$batch HTTP/1.1
Content-Type:multipart/mixed;boundary=batch_AAA123
Accept:application/json
OData-MaxVersion:4.0
OData-Version:4.0

--batch_AAA123
Content-Type: multipart/mixed; boundary=changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab

--changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1

POST [Organization URI]/api/data/v9.2/accounts HTTP/1.1
Content-Type: application/json

{ "name":"Account name"}

--changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 2

POST [Organization URI]/api/data/v9.2/contacts HTTP/1.1
Content-Type: application/json

{
  "firstname":"Contact first name"
}

--changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 3

PATCH $1 HTTP/1.1
Content-Type: application/json

{
  "primarycontactid@odata.bind":"$2"
}

--changeset_dd81ccab-11ce-4d57-b91d-12c4e25c3cab--
--batch_AAA123--

応答:

HTTP/1.1 200 OK
OData-Version: 4.0

--batchresponse_9595d3ae-48f6-414f-a3aa-a3a33559859e
Content-Type: multipart/mixed; boundary=changesetresponse_0c1567a5-ad0d-48fa-b81d-e6db05cad01c

--changesetresponse_0c1567a5-ad0d-48fa-b81d-e6db05cad01c
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 1

HTTP/1.1 204 No Content
OData-Version: 4.0
Location: [Organization URI]/api/data/v9.2/accounts(6cd81853-7b75-e911-a97a-000d3a34a1bd)
OData-EntityId: [Organization URI]/api/data/v9.2/accounts(6cd81853-7b75-e911-a97a-000d3a34a1bd)

--changesetresponse_0c1567a5-ad0d-48fa-b81d-e6db05cad01c
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 2

HTTP/1.1 204 No Content
OData-Version: 4.0
Location: [Organization URI]/api/data/v9.2/contacts(6ed81853-7b75-e911-a97a-000d3a34a1bd)
OData-EntityId: [Organization URI]/api/data/v9.2/contacts(6ed81853-7b75-e911-a97a-000d3a34a1bd)

--changesetresponse_0c1567a5-ad0d-48fa-b81d-e6db05cad01c
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-ID: 3

HTTP/1.1 204 No Content
OData-Version: 4.0
Location: [Organization URI]/api/data/v9.2/accounts(6cd81853-7b75-e911-a97a-000d3a34a1bd)
OData-EntityId: [Organization URI]/api/data/v9.2/accounts(6cd81853-7b75-e911-a97a-000d3a34a1bd)

--changesetresponse_0c1567a5-ad0d-48fa-b81d-e6db05cad01c--
--batchresponse_9595d3ae-48f6-414f-a3aa-a3a33559859e--

注意

要求本体で宣言される前に Content-ID を参照すると、エラー HTTP 400 無効な要求が返されます。

以下の例では、このエラーの原因となり得る要求本体を示しています。

要求本文

--batch_AAA123
Content-Type: multipart/mixed; boundary=changeset_BBB456

--changeset_BBB456
Content-Type: application/http
Content-Transfer-Encoding:binary
Content-ID: 2

POST [Organization URI]/api/data/v9.2/phonecalls HTTP/1.1
Content-Type: application/json;type=entry

{
    "phonenumber":"911",
    "regardingobjectid_account_phonecall@odata.bind" : "$1"
}

--changeset_BBB456
Content-Type: application/http
Content-Transfer-Encoding:binary
Content-ID: 1

POST [Organization URI]/api/data/v9.2/accounts HTTP/1.1
Content-Type: application/json;type=entry

{
    "name":"QQQQ",
    "revenue": 1.50
}

--changeset_BBB456--
--batch_AAA123--

応答:

HTTP 400 Bad Request
Content-ID Reference: '$1' does not exist in the batch context.

エラーを処理する

バッチ内の要求でエラーが発生した場合、その要求のエラーはバッチ要求に対して返され、それ以上のの要求は処理されません。

Prefer: odata.continue-on-error 要求ヘッダーを使用して、エラーが発生したときに、より多くの要求の処理を指定することができます。 バッチ要求が 200 OK を返し、個々の応答エラーは、バッチ応答本文に返されます。

詳細: OData 仕様: 8.2.8.3 プリファレンス odata.continue-on-error

次の例では、accountid00000000-0000-0000-0000-000000000001 に等しいアカウントに関連付けられた 3 つのタスク レコードを作成しようとしていますが、最初のタスクの subject プロパティの長さが長すぎます。

要求:

POST [Organization Uri]/api/data/v9.2/$batch HTTP/1.1
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
Content-Type: multipart/mixed; boundary="batch_431faf5a-f979-4ee6-a374-d242f8962d41"
Content-Length: 1335

--batch_431faf5a-f979-4ee6-a374-d242f8962d41
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-Length: 436

POST /api/data/v9.2/tasks HTTP/1.1
Content-Type: application/json; type=entry

{
  "subject": "Subject is too long xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "regardingobjectid_account_task@odata.bind": "accounts(00000000-0000-0000-0000-000000000001)"
}
--batch_431faf5a-f979-4ee6-a374-d242f8962d41
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-Length: 250

POST /api/data/v9.2/tasks HTTP/1.1
Content-Type: application/json; type=entry

{
  "subject": "Task 2 in batch",
  "regardingobjectid_account_task@odata.bind": "accounts(00000000-0000-0000-0000-000000000001)"
}
--batch_431faf5a-f979-4ee6-a374-d242f8962d41
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-Length: 250

POST /api/data/v9.2/tasks HTTP/1.1
Content-Type: application/json; type=entry

{
  "subject": "Task 3 in batch",
  "regardingobjectid_account_task@odata.bind": "accounts(00000000-0000-0000-0000-000000000001)"
}
--batch_431faf5a-f979-4ee6-a374-d242f8962d41--

Prefer: odata.continue-on-error 要求ヘッダーを設定しないと、バッチの最初の要求でバッチが失敗します。 バッチ エラーは、最初に失敗した要求のエラーを表します。

応答:

HTTP/1.1 400 BadRequest
OData-Version: 4.0

--batchresponse_156da4b8-cd2c-4862-a911-4aaab97c001a
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 400 Bad Request
REQ_ID: 5ecd1cb3-1730-4ffc-909c-d44c22270026
Content-Type: application/json; odata.metadata=minimal
OData-Version: 4.0

{"error":{"code":"0x80044331","message":"A validation error occurred.  The length of the 'subject' attribute of the 'task' entity exceeded the maximum allowed length of '200'."}}
--batchresponse_156da4b8-cd2c-4862-a911-4aaab97c001a--

Prefer: odata.continue-on-error 要求ヘッダーがバッチ要求に適用されると、バッチ要求は 200 OK のステータスで成功し、最初の要求の失敗が本文の一部として返されます。

要求:

POST [Organization Uri]/api/data/v9.2/$batch HTTP/1.1
Prefer: odata.continue-on-error
OData-MaxVersion: 4.0
OData-Version: 4.0
If-None-Match: null
Accept: application/json
Content-Type: multipart/mixed; boundary="batch_662d4610-7f12-4895-ac4a-3fdf77cc10a1"
Content-Length: 1338

--batch_662d4610-7f12-4895-ac4a-3fdf77cc10a1
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-Length: 439

POST /api/data/v9.2/tasks HTTP/1.1
Content-Type: application/json; type=entry

{
  "subject": "Subject is too long xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "regardingobjectid_account_task@odata.bind": "accounts(00000000-0000-0000-0000-000000000001)"
}
--batch_662d4610-7f12-4895-ac4a-3fdf77cc10a1
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-Length: 250

POST /api/data/v9.2/tasks HTTP/1.1
Content-Type: application/json; type=entry

{
  "subject": "Task 2 in batch",
  "regardingobjectid_account_task@odata.bind": "accounts(00000000-0000-0000-0000-000000000001)"
}
--batch_662d4610-7f12-4895-ac4a-3fdf77cc10a1
Content-Type: application/http
Content-Transfer-Encoding: binary
Content-Length: 250

POST /api/data/v9.2/tasks HTTP/1.1
Content-Type: application/json; type=entry

{
  "subject": "Task 3 in batch",
  "regardingobjectid_account_task@odata.bind": "accounts(00000000-0000-0000-0000-000000000001)"
}
--batch_662d4610-7f12-4895-ac4a-3fdf77cc10a1--

応答:

HTTP/1.1 200 OK
OData-Version: 4.0

--batchresponse_f44bd09d-573f-4a30-bca0-2e500ee7e139
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 400 Bad Request
REQ_ID: de4c5227-4a28-4ebd-8ced-3392ece1697b
Content-Type: application/json; odata.metadata=minimal
OData-Version: 4.0

{"error":{"code":"0x80044331","message":"A validation error occurred.  The length of the 'subject' attribute of the 'task' entity exceeded the maximum allowed length of '200'."}}
--batchresponse_f44bd09d-573f-4a30-bca0-2e500ee7e139
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 204 No Content
OData-Version: 4.0
Location: [Organization Uri]/api/data/v9.2/tasks(aed2ae8b-3c94-ed11-aad1-000d3a9933c9)
OData-EntityId: [Organization Uri]/api/data/v9.2/tasks(aed2ae8b-3c94-ed11-aad1-000d3a9933c9)


--batchresponse_f44bd09d-573f-4a30-bca0-2e500ee7e139
Content-Type: application/http
Content-Transfer-Encoding: binary

HTTP/1.1 204 No Content
OData-Version: 4.0
Location: [Organization Uri]/api/data/v9.2/tasks(b181a991-3c94-ed11-aad1-000d3a9933c9)
OData-EntityId: [Organization Uri]/api/data/v9.2/tasks(b181a991-3c94-ed11-aad1-000d3a9933c9)


--batchresponse_f44bd09d-573f-4a30-bca0-2e500ee7e139--

.NET ヘルパー メソッド

WebAPIService クラス ライブラリ (C#) は、.NET で記述された Web API サンプルに使用されるサンプル ヘルパー クラス ライブラリ プロジェクトです。 これは、Web API で使用される一般的なパターンを再利用できる 1 つの方法を示しています。

注意

このサンプル ライブラリは、すべての Dataverse C# Web API サンプルで使用されるヘルパーですが、SDK ではありません。 それを使用するサンプルが正常に動作することを確認するためだけにテストされます。 このサンプル コードは「現状のまま」提供され、再利用の保証はありません。

このライブラリには、バッチ要求を作成し、応答を処理するためのクラスが含まれています。 たとえば、次のコードのバリエーションを使用して、この記事の HTTP 要求と応答の例の多くを生成しました。

using PowerApps.Samples;
using PowerApps.Samples.Batch;

static async Task Main()
{
    Config config = App.InitializeApp();

    var service = new Service(config);

    JObject account = new()
    {
        {"name","test account" }
    };

    EntityReference accountRef = await service.Create("accounts", account);

    List<HttpRequestMessage> createRequests = new() {
        new CreateRequest("tasks",new JObject(){
            {"subject","Task 2 in batch" },
            {"regardingobjectid_account_task@odata.bind", accountRef.Path }
        }),
        new CreateRequest("tasks",new JObject(){
            {"subject","Task 2 in batch" },
            {"regardingobjectid_account_task@odata.bind", accountRef.Path }
        }),
        new CreateRequest("tasks",new JObject(){
            {"subject","Task 3 in batch" },
            {"regardingobjectid_account_task@odata.bind", accountRef.Path }
        })
    };

    BatchRequest batchRequest = new(service.BaseAddress)
    {
        Requests = createRequests,
        ContinueOnError = true
    };

    var batchResponse = await service.SendAsync<BatchResponse>(batchRequest);

    batchResponse.HttpResponseMessages.ForEach(response => {

        string path = response.As<CreateResponse>().EntityReference.Path;
        Console.WriteLine($"Task created at: {path}");
        
    });
}

出力

Task created at: tasks(6743adfa-4a94-ed11-aad1-000d3a9933c9)
Task created at: tasks(6843adfa-4a94-ed11-aad1-000d3a9933c9)
Task created at: tasks(6943adfa-4a94-ed11-aad1-000d3a9933c9)

このライブラリ内には、.NET コードで役立つメソッドがいくつかあります。

詳細情報:

.NET HttpRequestMessage から HttpMessageContent への例

.NET では、HttpContent のコレクションである MultipartContent としてバッチ要求を送信する必要があります。 HttpMessageContent は、HttpContent から継承されます。 WebAPIService クラス ライブラリ (C#) BatchRequest クラス は、次のプライベートな静的 ToMessageContent メソッドを使用して、MultipartContent に追加できる HttpRequestMessageHttpMessageContent に変換します。

/// <summary>
/// Converts a HttpRequestMessage to HttpMessageContent
/// </summary>
/// <param name="request">The HttpRequestMessage to convert.</param>
/// <returns>HttpMessageContent with the correct headers.</returns>
private HttpMessageContent ToMessageContent(HttpRequestMessage request)
{

    //Relative URI is not allowed with MultipartContent
    request.RequestUri = new Uri(
        baseUri: ServiceBaseAddress,
        relativeUri: request.RequestUri.ToString());

    if (request.Content != null)
    {
        if (request.Content.Headers.Contains("Content-Type"))
        {
            request.Content.Headers.Remove("Content-Type");
        }
        request.Content.Headers.Add("Content-Type", "application/json;type=entry");
    }

    HttpMessageContent messageContent = new(request);

    if (messageContent.Headers.Contains("Content-Type"))
    {
        messageContent.Headers.Remove("Content-Type");
    }
    messageContent.Headers.Add("Content-Type", "application/http");
    messageContent.Headers.Add("Content-Transfer-Encoding", "binary");

    return messageContent;

}

.NET 解析バッチ応答の例

WebAPIService クラス ライブラリ (C#) BatchResponse クラス は、次のプライベートな静的 ParseMultipartContent メソッドを使用して、バッチ応答の本文を個々の応答のように処理できる HttpResponseMessageList に解析します。

/// <summary>
/// Processes the Multi-part content returned from the batch into a list of responses.
/// </summary>
/// <param name="content">The Content of the response.</param>
/// <returns></returns>
private static async Task<List<HttpResponseMessage>> ParseMultipartContent(HttpContent content)
{
   MultipartMemoryStreamProvider batchResponseContent = await content.ReadAsMultipartAsync();

   List<HttpResponseMessage> responses = new();

   if (batchResponseContent?.Contents != null)
   {
         batchResponseContent.Contents.ToList().ForEach(async httpContent =>
         {

            //This is true for changesets
            if (httpContent.IsMimeMultipartContent())
            {
               //Recursive call
               responses.AddRange(await ParseMultipartContent(httpContent));
            }

            //This is for individual responses outside of a change set.
            else
            {
               //Must change Content-Type for ReadAsHttpResponseMessageAsync method to work.
               httpContent.Headers.Remove("Content-Type");
               httpContent.Headers.Add("Content-Type", "application/http;msgtype=response");

               HttpResponseMessage httpResponseMessage = await httpContent.ReadAsHttpResponseMessageAsync();

               if (httpResponseMessage != null)
               {
                     responses.Add(httpResponseMessage);
               }
            }
         });
   }

   return responses;
}

参照

Web API を使用して演算を実行する

注意

ドキュメントの言語設定についてお聞かせください。 簡単な調査を行います。 (この調査は英語です)

この調査には約 7 分かかります。 個人データは収集されません (プライバシー ステートメント)。