This is not usually the case but sometimes you may have a Fetch XML which is too large to be executed using a regular GET method and wish it had a post method. There is a way, by using Batch execution.
Things to note
Content-Type will be “multipart/mixed;boundary=mybatchname”
Data returned from the Web API cannot be directly parsed into JSON and needs some data-massaging.
Sample Code
var req = new XMLHttpRequest(); req.open("POST", Xrm.Page.context.getClientUrl() + "/api/data/v9.0/$batch", true); req.setRequestHeader("OData-MaxVersion", "4.0"); req.setRequestHeader("OData-Version", "4.0"); req.setRequestHeader("Accept", "application/json"); req.setRequestHeader("Content-Type", "multipart/mixed;boundary=mybatch"); req.onreadystatechange = function() { if (this.readyState === 4) { req.onreadystatechange = null; if (this.status === 200) { var results = JSON.parse(this.response.substring(this.response.indexOf('{'),this.response.lastIndexOf('}')+1)); } else { Xrm.Utility.alertDialog(this.statusText); } } }; var body = '--mybatch\n' body += 'Content-Type: application/http\n' body += 'Content-Transfer-Encoding: binary\n' body += '\n' body += 'GET ' + Xrm.Page.context.getClientUrl()+'/api/data/v9.0/accounts?fetchXml=<fetch count="10" ><entity name="account" ><attribute name="name" /></entity></fetch> HTTP/1.1\n' body += 'Content-Type: application/json\n' body += 'OData-Version: 4.0\n' body += 'OData-MaxVersion: 4.0\n' body += '\n' body += '--mybatch--' req.send(body);
- The POST URL is “$batch”
- Content-Type header contains the name of the batch
- Data returned from the Web API needs to be massaged to get the result
- Body of the request needs to be in certain format
Format of Request Body
--batchname Content-Type: application/http Content-Transfer-Encoding: binary GET https://[CRM URL]/api/data/[CRM API Version]/[Entity's Plural Name]?fetchXml=[Fetch XML] HTTP/1.1 Content-Type: application/json OData-Version: 4.0 OData-MaxVersion: 4.0 --batchname--
Formatting Response Data
Actual Response from Web API
--batchresponse_BatchGUID Content-Type: application/http Content-Transfer-Encoding: binary HTTP/1.1 200 OK Access-Control-Expose-Headers: Preference-Applied,OData-EntityId,Location,ETag,OData-Version,Content-Encoding,Transfer-Encoding,Content-Length,Retry-After Content-Type: application/json; odata.metadata=minimal OData-Version: 4.0 {"@odata.context":"https://[CRM URL]/api/data/v[CRM API Version]/$metadata#accounts(name,accountid)","@Microsoft.Dynamics.CRM.fetchxmlpagingcookie":"","value":[{"@odata.etag":"W/\"70232774\"","name":"XYZ1","accountid":"GUID1"},{"@odata.etag":"W/\"70348872\"","name":"XYZ2","accountid":"GUID2"}]} --batchresponse_BatchGUID--
If you observe the actual data inside the batchresponse is between { and }. Hence we get the substring of the actual response using the code below.
var results = JSON.parse(this.response.substring(this.response.indexOf('{'),this.response.lastIndexOf('}')+1));
Hope this helps.
But there is a problem. if one of the first returned record’s fields doesn’t have value then other records will not contain those fields!!
This link will be more descriptive:
https://stackoverflow.com/questions/56491739/data-missing-retrieving-data-using-the-api-8-2
LikeLike
I haven’t tested the scenario you described. Good to know. Thanks.
LikeLike
Hi Danish,
I am trying to do paging based of the batch fetchxml but somehow it is returning the same paging cookie. Any idea what is going wrong ?
Thanks
LikeLike