バッチ操作を使用して、複数の操作を 1 つの HTTP 要求にグループ化できます。 Dataverse は、指定した順序でこれらの操作を順番に実行します。 応答の順序は、バッチ操作の要求の順序と一致します。
$batch要求を送信するための形式は、OData 仕様の 11.7 バッチ要求で定義されています。 この記事では、仕様の要件を要約し、Dataverse 固有の情報と例を示します。
バッチ要求を使用する場合
バッチ要求には、一緒に使用できる 2 つの機能が用意されています。
1 回の HTTP 要求で複数の操作の要求を送信することができます。
- バッチ要求には最大 1,000 個の個別の要求を含めることができます。また、他のバッチ要求を含めることはできません。
- Web API
$batch要求は、SDK for .NET で利用可能なExecuteMultipleメッセージと同等です。 詳細については、「 SDK for .NET を使用して複数の要求を実行する」を参照してください。
操作の要求をグループ化して、 変更セットを使用して 1 つのトランザクションとして含めることができます。
- すべての操作がグループとして成功または失敗することを保証する方法で、関連レコードのセットを作成、更新、または削除することができます。
- 変更セットを使用した Web API
$batch要求は、SDK for .NET で使用できるExecuteTransactionメッセージと同じです。 詳細については、「 単一データベース トランザクションでのメッセージの実行」を参照してください。
ヒント
関連付けられたエンティティは、バッチ要求を使用するよりも簡単に 1 回の操作で作成できます。 詳細については、「 1 回の操作で関連するテーブル行を作成する」を参照してください。
URL の長さがGET長を超える可能性がある場合、バッチ要求を使用して要求を送信することがあります。 バッチ要求を使用すると、最大 64 KB (65,536 文字) の URL が許可されているメッセージの本文に要求の URL を含めることができます。 FetchXml を使用して複雑なクエリを送信すると、長い URL が生成される可能性があります。 詳細については、 バッチ要求内での FetchXML の使用を参照してください。
Web API を使用して実行できる他の操作と比較すると、バッチ要求の作成が困難になります。 raw 要求と応答の本文は、基本的に、特定の要件に一致する必要があるテキスト ドキュメントです。 応答でこのデータにアクセスするには、応答内のテキストを解析するか、応答内のデータにアクセスするためのヘルパー ライブラリを検索する必要があります。 .NET ヘルパー メソッド を参照してください。
バッチ要求
POST 要求を使用して、複数の要求が含まれているバッチ操作を送信します。
バッチを含むPOST要求には、次のパターンを使用してバッチの識別子を含めるように設定された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 行末尾を追加して、ほとんどの逆シリアル化エラーを解決できます。
次の例は、変更セットを使用しないバッチ要求です。 この例では:
-
accountidが00000000-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(00aa00aa-bb11-cc22-dd33-44ee44ee44ee)
OData-EntityId: [Organization Uri]/api/data/v9.2/tasks(00aa00aa-bb11-cc22-dd33-44ee44ee44ee)
--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(11bb11bb-cc22-dd33-ee44-55ff55ff55ff)
OData-EntityId: [Organization Uri]/api/data/v9.2/tasks(11bb11bb-cc22-dd33-ee44-55ff55ff55ff)
--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(22cc22cc-dd33-ee44-ff55-66aa66aa66aa)
OData-EntityId: [Organization Uri]/api/data/v9.2/tasks(22cc22cc-dd33-ee44-ff55-66aa66aa66aa)
--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": "00aa00aa-bb11-cc22-dd33-44ee44ee44ee"
},
{
"@odata.etag": "W/\"77180910\"",
"subject": "Task 2 in batch",
"activityid": "11bb11bb-cc22-dd33-ee44-55ff55ff55ff"
},
{
"@odata.etag": "W/\"77180913\"",
"subject": "Task 3 in batch",
"activityid": "22cc22cc-dd33-ee44-ff55-66aa66aa66aa"
}
]
}
--batchresponse_01346794-f2e2-4d45-8cc2-f97e09fe8916--
変更セット
バッチ要求には、個々の要求に加えて変更セットを含めることができます。 複数の操作が変更セットに含まれている場合、すべての操作は アトミック と見なされます。 アトミック操作とは、いずれかの操作が失敗した場合、バッチ要求が完了した操作をロールバックすることを意味します。
ヒント
GET 要求は変更セット内では許可されません。
GET操作はデータを変更しないため、変更セット内に属しません。
バッチ要求と同様に、変更セットには ヘッダーが必要で、その値はに設定され、次のパターンを使用して変更セットの識別子を含める必要があります。
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 ヘッダーを含めることもできます。 この値は、後で変更セットに , represents a variable that contains the URI for any entity created in that operation. For example, when you set the value of 1, you can refer to that entity by using $1` が付いた場合に使用されます。 詳細については、 操作の参照 URI に関するページを参照してください。
変更セットの最後には、次の例のように、終端のインジケーターを含める必要があります。
--changeset_<unique identifier>--
次の例は、変更セットの使用方法を示しています:
-
accountid値00000000-0000-0000-0000-000000000001のアカウントに関連付けられた 3 つのタスクの作成をグループ化します。 - 変更セットの外部で
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(33dd33dd-ee44-ff55-aa66-77bb77bb77bb)
OData-EntityId: [Organization Uri]/api/data/v9.2/tasks(33dd33dd-ee44-ff55-aa66-77bb77bb77bb)
--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(44ee44ee-ff55-aa66-bb77-88cc88cc88cc)
OData-EntityId: [Organization Uri]/api/data/v9.2/tasks(44ee44ee-ff55-aa66-bb77-88cc88cc88cc)
--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(55ff55ff-aa66-bb77-cc88-99dd99dd99dd)
OData-EntityId: [Organization Uri]/api/data/v9.2/tasks(55ff55ff-aa66-bb77-cc88-99dd99dd99dd)
--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": "33dd33dd-ee44-ff55-aa66-77bb77bb77bb"
},
{
"@odata.etag": "W/\"77181176\"",
"subject": "Task 2 in batch",
"activityid": "44ee44ee-ff55-aa66-bb77-88cc88cc88cc"
},
{
"@odata.etag": "W/\"77181179\"",
"subject": "Task 3 in batch",
"activityid": "55ff55ff-aa66-bb77-cc88-99dd99dd99dd"
}
]
}
--batchresponse_f27ef42d-51b0-4685-bac9-f468f844de2f--
運用における参照URI
変更セット内では、$parameter、$1などの$2を使用して、同じ変更セットで前に作成された新しいエンティティに対して返される URI を参照できます。 詳細については、OData v4.0 の仕様を参照してください: 11.7.3.1 変更セット内の要求の参照。
このセクションでは、バッチ操作の要求本文で $parameter を使用して URI を参照する方法のさまざまな例を示します。
リクエストボディ内のURI参照
次の例は、1 回の操作で 2 つの 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/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(66aa66aa-bb77-cc88-dd99-00ee00ee00ee)
OData-EntityId: [Organization URI]/api/data/v9.2/leads(66aa66aa-bb77-cc88-dd99-00ee00ee00ee)
--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(00aa00aa-bb11-cc22-dd33-44ee44ee44ee)
OData-EntityId: [Organization URI]/api/data/v9.2/contacts(00aa00aa-bb11-cc22-dd33-44ee44ee44ee)
--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(11bb11bb-cc22-dd33-ee44-55ff55ff55ff)
OData-EntityId: [Organization URI]/api/data/v9.2/accounts(11bb11bb-cc22-dd33-ee44-55ff55ff55ff)
--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(22cc22cc-dd33-ee44-ff55-66aa66aa66aa)
OData-EntityId:[Organization URI]/api/data/v9.2/contacts(22cc22cc-dd33-ee44-ff55-66aa66aa66aa)
--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--
@odata.id を使用して URI を URL と要求本文で参照する
以下の例では、取引先担当者 エンティティー レコードを、取引先企業 エンティティー レコードにリンクする方法を示しています。 Account エンティティ レコードの URI は $1 として参照され、Contact エンティティ レコードの 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(33dd33dd-ee44-ff55-aa66-77bb77bb77bb)
OData-EntityId:[Organization URI]/api/data/v9.2/accounts(33dd33dd-ee44-ff55-aa66-77bb77bb77bb)
--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(44ee44ee-ff55-aa66-bb77-88cc88cc88cc)
OData-EntityId:[Organization URI]/api/data/v9.2/contacts(44ee44ee-ff55-aa66-bb77-88cc88cc88cc)
--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 単一値ナビゲーション プロパティを使用して取引先企業レコードにリンクする方法を示しています。 Account エンティティ レコードの URI は$1として参照され、Contact エンティティ レコードの URI は$2要求でPATCHとして参照されます。
要求:
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(55ff55ff-aa66-bb77-cc88-99dd99dd99dd)
OData-EntityId: [Organization URI]/api/data/v9.2/accounts(55ff55ff-aa66-bb77-cc88-99dd99dd99dd)
--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(66aa66aa-bb77-cc88-dd99-00ee00ee00ee)
OData-EntityId: [Organization URI]/api/data/v9.2/contacts(66aa66aa-bb77-cc88-dd99-00ee00ee00ee)
--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(55ff55ff-aa66-bb77-cc88-99dd99dd99dd)
OData-EntityId: [Organization URI]/api/data/v9.2/accounts(55ff55ff-aa66-bb77-cc88-99dd99dd99dd)
--changesetresponse_0c1567a5-ad0d-48fa-b81d-e6db05cad01c--
--batchresponse_9595d3ae-48f6-414f-a3aa-a3a33559859e--
ヒント
要求本文に表示される前に Content-ID を参照すると、 エラー HTTP 400 Bad 要求が返されます。
以下の例では、このエラーの原因となり得る要求本体を示しています。
リクエストボディ
--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
例
次の例では、accountid が 00000000-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(00aa00aa-bb11-cc22-dd33-44ee44ee44ee)
OData-EntityId: [Organization Uri]/api/data/v9.2/tasks(00aa00aa-bb11-cc22-dd33-44ee44ee44ee)
--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(11bb11bb-cc22-dd33-ee44-55ff55ff55ff)
OData-EntityId: [Organization Uri]/api/data/v9.2/tasks(11bb11bb-cc22-dd33-ee44-55ff55ff55ff)
--batchresponse_f44bd09d-573f-4a30-bca0-2e500ee7e139--
.NET ヘルパー メソッド
WebAPIService クラス ライブラリ (C#) は、.NET で記述された Web API サンプル用のサンプル ヘルパー クラス ライブラリ プロジェクトです。 Web API で使用される一般的なパターンを再利用する 1 つの方法を示します。
ヒント
このサンプル ライブラリは、すべての Dataverse C# Web API サンプルで使用されるヘルパーですが、SDK ではありません。 これは、それを使用するサンプルが正常に実行されることを確認するためにのみテストされます。 このサンプル コードは、再利用の保証なしで "as-is" が提供されます。
このライブラリには、バッチ要求を作成し、応答を処理するためのクラスが含まれています。 たとえば、次のコードのバリエーションを使用して、この記事の 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 では、MultipartContent のコレクションであるとしてバッチ要求を送信する必要があります。
HttpMessageContent は、HttpContent から継承されます。
WebAPIService クラス ライブラリ (C#)BatchRequest クラスは、次のプライベート静的ToMessageContent メソッドを使用して、HttpRequestMessageをHttpMessageContentに追加できるMultipartContentに変換します。
/// <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 メソッドを使用して、バッチ応答の本文を、個々の応答のように処理できる List のに解析します。
/// <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;
}