OData REST API batch UPDATE, DELETE and INSERT requests are accepted by the Dynamics 365 F&O server and the requests return the expected HTTP responses for success, but the changes are not reflected on the server. Performing the same series of operations using the individual requests that were included in the batch request return the identical responses for success and the changes are correctly reflected on the server.
Is this a bug in the Dynamics F&O REST API or do OData REST batch requests require something other than what is specified in the OData 4 specification?
Here is an example POST in PostMan where 2 rows are deleted in a batch operation followed by the success response returned from the server. Even though the response shows the deletes were successful the 2 rows still exist on the server.
POST /data/$batch HTTP/1.1[\r][\n]"
"Accept: multipart/mixed[\r][\n]"
"Content-Type: multipart/mixed;boundary=batch_d1c614d9-86a9-479c-898e-9d17faa39436[\r][\n]"
"OData-MaxVersion: 4.0[\r][\n]"
"OData-Version: 4.0[\r][\n]"
"Prefer: odata.continue-on-error[\r][\n]"
"Content-Length: 862[\r][\n]"
"Host: dci-devdevaos.sandbox.ax.dynamics.com[\r][\n]"
"Connection: Keep-Alive[\r][\n]"
"User-Agent: Apache-HttpClient/4.5.7 (Java/1.8.0_212)[\r][\n]"
"Authorization: Bearer <insert access token here>[\r][\n]"
"[\r][\n]"
"[\r][\n]"
"--batch_d1c614d9-86a9-479c-898e-9d17faa39436[\r][\n]"
"Content-Type: application/http[\r][\n]"
"Content-Transfer-Encoding: binary[\r][\n]"
"Content-ID:b5bbbdcc-1622-4313-bbdb-9577a0e5bcaa[\r][\n]"
"[\r][\n]"
"DELETE /data/RetailDevices('TEST11') HTTP/1.1[\r][\n]"
"Accept: application/json;odata.metadata=full[\r][\n]"
"Content-Type: application/json;odata.metadata=full[\r][\n]"
"OData-MaxVersion: 4.0[\r][\n]"
"OData-Version: 4.0[\r][\n]"
"Content-ID: b5bbbdcc-1622-4313-bbdb-9577a0e5bcaa[\r][\n]"
"[\r][\n]"
"[\r][\n]"
"--batch_d1c614d9-86a9-479c-898e-9d17faa39436[\r][\n]"
"Content-Type: application/http[\r][\n]"
"Content-Transfer-Encoding: binary[\r][\n]"
"Content-ID:6f7f64ff-4880-4dc6-a3d0-207dbfb078d4[\r][\n]"
"[\r][\n]"
"DELETE /data/RetailDevices('TEST12') HTTP/1.1[\r][\n]"
"Accept: application/json;odata.metadata=full[\r][\n]"
"Content-Type: application/json;odata.metadata=full[\r][\n]"
"OData-MaxVersion: 4.0[\r][\n]"
"OData-Version: 4.0[\r][\n]"
"Content-ID: 6f7f64ff-4880-4dc6-a3d0-207dbfb078d4[\r][\n]"
"[\r][\n]"
"[\r][\n]"
"--[\r][\n]"
"HTTP/1.1 200 OK[\r][\n]"
"Content-Type: multipart/mixed; boundary=batchresponse_9f4bd7b4-d9cd-4cee-b314-43ca4ead8881[\r][\n]"
"Server: Microsoft-IIS/10.0[\r][\n]"
"Strict-Transport-Security: max-age=31536000; includeSubDomains[\r][\n]"
"OData-Version: 4.0[\r][\n]"
"ms-dyn-fqhn: [\r][\n]"
"ms-dyn-namespace: AxProdDevTest[\r][\n]"
"ms-dyn-tenant: lcs-10e54ad3-4872-49ea-afa9-965b4a218736[\r][\n]"
"ms-dyn-role: [\r][\n]"
"ms-dyn-aid: a1d83f78-5768-0002-e2b6-dba16857d601[\r][\n]"
"X-Content-Type-Options: nosniff[\r][\n]"
"X-Frame-Options: SAMEORIGIN[\r][\n]"
"p3p: CP="No P3P policy defined. Read the Microsoft privacy statement at "">go.microsoft.com/.../
"Strict-Transport-Security: max-age=31536000; includeSubDomains[\r][\n]"
"Date: Tue, 14 Jul 2020 17:33:50 GMT[\r][\n]"
"Content-Length: 360[\r][\n]"
"[\r][\n]"
"--batchresponse_9f4bd7b4-d9cd-4cee-b314-43ca4ead8881[\r][\n]"
"Content-Type: application/http[\r][\n]"
"Content-Transfer-Encoding: binary[\r][\n]"
"[\r][\n]"
"HTTP/1.1 204 No Content[\r][\n]"
"[\r][\n]"
"[\r][\n]"
"--batchresponse_9f4bd7b4-d9cd-4cee-b314-43ca4ead8881[\r][\n]"
"Content-Type: application/http[\r][\n]"
"Content-Transfer-Encoding: binary[\r][\n]"
"[\r][\n]"
"HTTP/1.1 204 No Content[\r][\n]"
"[\r][\n]"
"[\r][\n]"
"--[\r][\n]