Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Sie können mehrere Vorgänge mithilfe eines Batchvorgangs in einer einzelnen HTTP-Anforderung gruppieren. Dataverse führt diese Vorgänge sequenziell in der von Ihnen angegebenen Reihenfolge aus. Die Reihenfolge der Antworten entspricht der Reihenfolge der Anforderungen im Batchvorgang.
Das Format für das Senden von $batch Anforderungen wird in 11.7 Batchanforderungen in der OData-Spezifikation definiert. In diesem Artikel werden die Spezifikationsanforderungen zusammengefasst und Dataverse-spezifische Informationen und Beispiele bereitgestellt.
Wann Batchanforderungen verwendet werden sollten
Batchanforderungen bieten zwei Funktionen, die Sie zusammen verwenden können:
Sie können Anforderungen für mehrere Vorgänge mit einer einzigen HTTP-Anforderung senden.
- Batchanforderungen können bis zu 1.000 einzelne Anforderungen enthalten und können keine anderen Batchanforderungen enthalten.
- Web-API-
$batch-Anforderungen entsprechen derExecuteMultiple-Nachricht, die im SDK für .NET verfügbar ist. Weitere Informationen finden Sie unter Ausführen mehrerer Anforderungen mit dem SDK für .NET.
Mithilfe von Änderungssätzen können Sie Anforderungen für Vorgänge gruppieren, sodass sie als einzelne Transaktion einbezogen werden.
- Möglicherweise möchten Sie eine Reihe verwandter Datensätze erstellen, löschen oder aktualisieren, wobei garantiert wird, dass alle Vorgänge als Gruppe gelingen oder fehlschlagen.
- Web-API-Anforderungen
$batchmithilfe von Änderungssätzen entsprechen der Nachricht, dieExecuteTransactionim SDK für .NET verfügbar ist. Weitere Informationen finden Sie unter Ausführen von Nachrichten in einer einzelnen Datenbanktransaktion.
Anmerkung
Sie können zugeordnete Entitäten in einem einzelnen Vorgang einfacher erstellen als mithilfe einer Batchanforderung. Weitere Informationen finden Sie unter Erstellen verwandter Tabellenzeilen in einem Vorgang.
Leute nutzen manchmal Batchanforderungen, um GET Anforderungen zu senden, wenn die Länge der URL möglicherweise die maximal zulässige URL-Länge überschreitet. Mithilfe von Batchanforderungen fügen Sie die URL für die Anforderung im Textkörper der Nachricht ein, bei der eine URL bis zu 64 KB (65.536 Zeichen) zulässig ist. Das Senden komplexer Abfragen mithilfe von FetchXml kann zu langen URLs führen. Weitere Informationen finden Sie unter Verwenden von FetchXML innerhalb einer Batchanforderung.
Im Vergleich zu anderen Vorgängen, die Sie mithilfe der Web-API ausführen können, sind Batchanforderungen schwieriger zu verfassen. Bei den rohen Anfordeungs- und Antworttexten handelt es sich im Wesentlichen um ein Textdokument, das bestimmten Anforderungen entsprechen muss. Um auf die Daten in einer Antwort zuzugreifen, müssen Sie den Text in der Antwort analysieren oder eine Hilfsbibliothek finden. Siehe .NET-Hilfsmethoden.
Batchanforderungen
Nutzen Sie eine POST-Anfrage, um eine Batch-Operation zu senden, die mehrere Anforderungen enthält.
Die POST Anforderung, die den Batch enthält, muss über einen Inhaltstypheader mit einem Wert verfügen, der multipart/mixed mit einem boundary Satz festgelegt ist, um den Bezeichner des Batches mithilfe dieses Musters einzuschließen:
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>"
Der eindeutige Bezeichner muss keine GUID sein, sollte aber eindeutig sein.
Jedem Element innerhalb des Batches muss der Batchbezeichner sowie ein Content-Type und ein Header für die Inhaltsübertragungscodierung vorangestellt werden, wie im folgenden Beispiel gezeigt:
--batch_<unique identifier>
Content-Type: application/http
Content-Transfer-Encoding: binary
Wichtig
Nur Nutzlastelemente mit einem Batchbezeichner, der dem im Content-Type Header gesendeten Batchbezeichner entspricht, werden ausgeführt. Wenn kein Nutzlastelement den Content-Type Batchbezeichner verwendet, wird die Batchanforderung erfolgreich ausgeführt, ohne ein Nutzlastelement auszuführen.
Sie müssen alle anderen HTTP-Header für jedes Element im Stapel einbeziehen, um das Verhalten für diese Anforderung zu steuern. Auf den $batch Vorgang angewendete Kopfzeilen gelten nicht für jedes Element. Wenn Sie beispielsweise eine GET-Anforderung einbeziehen und Anmerkungen anfordern möchten, müssen Sie den entsprechenden Prefer: odata.include-annotations="*"-Header zu jedem Element hinzufügen.
Das Ende der Batchanforderung muss einen Beendigungsindikator enthalten, wie im folgenden Beispiel gezeigt:
--batch_<unique identifier>--
Anmerkung
Das HTTP-Protokoll erfordert, dass alle Zeilenenden in $batch Anforderungslasten CRLF sind.
Andere Zeilenenden können zu Deserialisierungsfehlern führen. Beispiel: System.ArgumentException: Stream was not readable.. Wenn Sie CRLF nicht verwenden können, können Sie am Ende der Anforderungsnutzlast zwei Nicht-CRLF-Zeilenende hinzufügen, um die meisten Deserialisierungsfehler zu beheben.
Das folgende Beispiel ist eine Batch-Anforderung ohne Änderungssätze. Dieses Beispiel:
- Erstellt drei Aufgabendatensätze, die einem Konto mit
accountidgleich00000000-0000-0000-0000-000000000001zugeordnet sind. - Ruft die dem Konto zugeordneten Aufgabendatensätze ab.
Anforderung:
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--
Stapelantworten
Bei Erfolg gibt die Batchantwort den HTTP-Status 200 OK zurück. Jedes Element in der Antwort wird durch einen Guid eindeutigen Bezeichnerwert getrennt, der nicht mit dem Batchanforderungswert übereinstimmt.
--batchresponse_<unique identifier>
Content-Type: application/http
Content-Transfer-Encoding: binary
Das Ende der Batchantwort enthält einen Beendigungsindikator, wie im folgenden Beispiel gezeigt:
--batchresponse_<unique identifier>--
Das folgende Beispiel zeigt die Antwort auf das vorherige Batchanforderungsbeispiel.
Antwort:
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--
Änderungspakete
Eine Batchanforderung kann neben individuellen Anforderungen auch Änderungssätze enthalten. Wenn mehrere Vorgänge in einem Changeset enthalten sind, werden alle Vorgänge als atomar betrachtet. Ein atomarer Vorgang bedeutet, dass die Batchanforderung alle bereits durchgeführten Vorgänge rückgängig macht, wenn einer der Vorgänge fehlschlägt.
Anmerkung
GET Anforderungen sind innerhalb von Änderungssätzen nicht zulässig. Ein GET Vorgang ändert keine Daten, sodass er nicht innerhalb eines Änderungssatzes gehört.
Wie bei einer Batchanforderung müssen Änderungssätze einen Content-Type-Header mit einem Wert aufweisen, der auf multipart/mixed festgelegt ist, wobei boundary verwendet wird, um den Bezeichner des Änderungssatzes mithilfe dieses Musters einzuschließen:
Content-Type: multipart/mixed; boundary="changeset_<unique identifier>"
Der eindeutige Bezeichner muss keine GUID sein, sollte aber eindeutig sein. Jedem Element im Änderungssatz muss der Änderungssatzbezeichner vorausgehen mit einem Content-Type- und Content-Transfer-Encoding-Header wie im folgenden Beispiel:
--changeset_<unique identifier>
Content-Type: application/http
Content-Transfer-Encoding: binary
Änderungssätze können auch einen Content-ID-Header mit einem eindeutigen Wert enthalten. Dieser Wert, wenn er später in Ihrem Änderungssatz mit , 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` vorangestellt wird. Weitere Informationen finden Sie unter Referenz-URIs in einem Vorgang.
Das Ende des Änderungssatzes muss einen Indikator für das Beenden wie das folgende Beispiel enthalten:
--changeset_<unique identifier>--
Das folgende Beispiel zeigt die Verwendung eines Changesets für Folgendes:
- Gruppieren Sie die Erstellung von drei Aufgaben, die einem Konto mit dem
accountid-Wert00000000-0000-0000-0000-000000000001zugeordnet sind. - Rufen Sie die Konten ab, die mithilfe einer
GETAnforderung außerhalb des Änderungssatzes erstellt wurden.
Anforderung:
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--
Antwort:
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--
Verweis-URIs in einer Operation
Innerhalb von Changesets können Sie beispielsweise $parameter, $1, $2 usw. verwenden, um auf URIs zu verweisen, die für neue Entitäten zurückgegeben wurden, die zuvor im gleichen Changeset erstellt wurden. Weitere Informationen finden Sie in der OData v4.0-Spezifikation: 11.7.3.1 Verweisen auf Anforderungen in einem Changeset.
In diesem Abschnitt werden verschiedene Beispiele für die Verwendung $parameter im Anforderungstext eines Batchvorgangs zum Verweisen auf URIs gezeigt.
Verweis-URIs im Anforderungstext
Das folgende Beispiel zeigt, wie zwei URI-Verweise in einem einzigen Vorgang verwendet werden.
Anforderung:
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--
Antwort:
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--
Verweis-URI in der Anforderungs-URL
Das folgende Beispiel zeigt, wie Sie auf einen URI mithilfe von $1 in der URL einer nachfolgenden Anforderung verweisen.
Anforderung:
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--
Antwort:
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--
Verweisen auf URIs in URL und Anforderungstext mithilfe von @odata.id
Das nachfolgende Beispiel zeigt, wie Sie einen Kontaktentitätsdatensatz mit einem Firmenentitätsdatensatz verknüpfen. Auf den URI des Kontenentität-Datensatzes wird mit $1 verwiesen, und der URI des Kontaktentität-Datensatzes wird mit $2 referenziert.
Anforderung:
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--
Antwort:
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--
Verweis-URIs in der URL und Navigationseigenschaften
Das folgende Beispiel zeigt, wie Sie den Organisations-URI eines Kontaktdatensatzes verwenden und ihn mit einem Kontodatensatz verknüpfen, indem Sie die primarycontactid Einzelwert-Navigationseigenschaft verwenden. Auf den URI des Kontoentitätsdatensatzes wird als $1 und auf den URI des Datensatzes der Kontaktentität als $2 in der PATCH-Anforderung verwiesen.
Anforderung:
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--
Antwort:
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--
Anmerkung
Das Verweisen auf eine Content-ID bevor es im Anforderungstext erscheint, gibt den Fehler HTTP 400 Fehlerhafte Anforderung zurück.
Das folgende Beispiel zeigt Anforderungstext an, der diesen Fehler verursachen kann.
Anforderungstext
--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--
Antwort:
HTTP 400 Bad Request
Content-ID Reference: '$1' does not exist in the batch context.
Behandeln von Fehlern
Wenn ein Fehler für eine Anforderung innerhalb eines Batches auftritt, gibt die Batchanforderung den Fehler für diese Anforderung zurück und verarbeitet keine weiteren Anforderungen.
Wenn Sie den Anforderungsheader Prefer: odata.continue-on-error hinzufügen, können Sie angeben, dass der Server weitere Anforderungen verarbeitet, wenn Fehler auftreten. Die Batchanforderung gibt zurück 200 OK, und einzelne Antwortfehler sind im Batchantworttext enthalten.
Mehr Informationen: OData-Spezifikation: 8.2.8.3 Präferenz odata.continue-on-error
Beispiel
Im folgenden Beispiel wird versucht, drei Aufgabendatensätze zu erstellen, die einem Konto mit accountid, das 00000000-0000-0000-0000-000000000001 entspricht, zugeordnet sind, aber die Länge der Eigenschaft subject für die erste Aufgabe ist zu groß.
Anforderung:
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--
Ohne Festlegen des Prefer: odata.continue-on-error-Anforderungsheaders schlägt der Batch bei der ersten Anforderung im Batch fehl. Der Batchfehler stellt den Fehler der ersten fehlgeschlagenen Anforderung dar.
Antwort:
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--
Wenn Sie der Batchanforderung den Anforderungsheader Prefer: odata.continue-on-error hinzufügen, wird die Batchanforderung erfolgreich mit einem Status 200 OK ausgeführt, und der Fehler der ersten Anforderung wird als Teil des Textkörpers zurückgegeben.
Anforderung:
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--
Antwort:
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-Hilfsmethoden
Die WebAPIService-Klassenbibliothek (C#) ist ein Beispielhilfsklassenbibliotheksprojekt für Web-API-Beispiele, die in .NET geschrieben wurden. Es veranschaulicht eine Möglichkeit, allgemeine Muster wiederzuverwenden, die mit der Web-API verwendet werden.
Anmerkung
Diese Beispielbibliothek ist ein Hilfsprogramm, das von allen Dataverse C#-Web-API-Beispielen verwendet wird, es handelt sich jedoch nicht um ein SDK. Es wird nur getestet, um zu bestätigen, dass die Beispiele, die es verwenden, erfolgreich ausgeführt werden. Dieser Beispielcode wird "as-is" ohne Garantie für die Wiederverwendung bereitgestellt.
Diese Bibliothek enthält Klassen zum Erstellen von Batchanforderungen und zum Verarbeiten von Antworten. Beispielsweise wurden Variationen des folgenden Codes verwendet, um viele der BEISPIELE für HTTP-Anforderung und Antwort in diesem Artikel zu generieren.
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}");
});
}
Ausgabe
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)
In dieser Bibliothek finden Sie möglicherweise einige Methoden, die für Ihren .NET-Code nützlich sind.
Weitere Informationen:
Beispiel einer .NET-HttpRequestMessage zu HttpMessageContent
In .NET müssen Sie Batchanforderungen als MultipartContent, die eine Sammlung von HttpContent ist, senden.
HttpMessageContent erbt von HttpContent. Die WebAPIService-Klassenbibliothek (C#)BatchRequest-Klasse verwendet die folgende private statische ToMessageContent-Methode, um HttpRequestMessage in HttpMessageContent zu konvertieren, die Sie zu MultipartContent hinzufügen können.
/// <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;
}
Beispiel für eine .NET-Batch-Antwort auf Parse
Die WebAPIService-Klassenbibliothek (C#)BatchResponse-Klasse verwendet die folgende private statische ParseMultipartContent Methode, um den Textkörper einer Batchantwort in eine ListHttpResponseMessage zu analysieren, die Sie wie einzelne Antworten verarbeiten können.
/// <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;
}