Hi. I need to make a query that takes all products that exists in our CRM. for thata i did the following JS code
var tmp = null;
var count = 1
globalResult = new Array();
do{
debugger
/*make the query */
tmp = SdkWebAPI.getFetchXml(logicalName, fetch);
/*and populate the globalResult*/
for (j = 0; j < tmp.Value.length; j++) {
globalResult .push(tmp.Value[j]);
}
if(tmp.PagingCookie){
/*get paging cookie */
var pagingcookie = window.DOMParser ? (new DOMParser()).parseFromString(tmp.PagingCookie, "text/xml").activeElement.getAttribute("pagingcookie") : new ActiveXObject("Microsoft.XMLDOM").loadXML(tmp.PagingCookie).activeElement.getAttribute("pagingcookie")
/*double decode and format. */
var dec_uri = decodeURIComponent(pagingcookie)
var dec_uri2 = decodeURIComponent(dec_uri)
dec_uri2 = dec_uri2.replaceAll('<', '<')
dec_uri2 = dec_uri2.replaceAll('>', '>')
dec_uri2 = dec_uri2.replaceAll('"', '&quot;')
dec_uri2 = dec_uri2.replaceAll('\"', '"')
/*Format the old fetch */
fetch = fetch.replace('page=\"'+ count+'\"', 'page=\"'+ ++count + '\" paging-cookie=\"' + dec_uri2 + '\"')
}
}while(tmp.HasMoreRecords);
The final fetch works on XRM toolbox and it's something like:
<fetch version="1.0" output-format="xml-platform" mapping="logical" distinct="true" page="2" paging-cookie="<cookie page="1"><name last="LID 5X1.5" first="&quot;MAC6&quot; LM&quot;" /><productid last="{B73E51BC-7355-E711-80FD-C4346BAC6E90}" first="{9150B21C-5423-E611-80E4-5065F38A3B71}" /></cookie>" >
<entity name="product" >
<attribute name="productid" />
<attribute name="name" />
<attribute name="productnumber" />
<order attribute="name" descending="false" />
</entity>
</fetch>
The problem is that when i try to make the request usin OData it's always returning an error: "An item with the same key has already been added"
I check the following links:
http://azurefunda.blogspot.com/2018/05/retrieve-5000-records-in-dynamics-crm.html
https://www.inogic.com/blog/2015/07/querying-more-than-5000-records-in-dynamics-crm/
https://stackoverflow.com/questions/39593820/ms-dynamics-rest-api-fetchxml-with-a-paging-cookie
And try different paging-cookies: Now, a list of them and the error that i receive on each one:
Original fetch = "<fetch version=\"1.0\" output-format=\"xml-platform\" mapping=\"logical\" distinct=\"true\" page=\"1\"><entity name=\"product\"><attribute name=\"productid\" /><attribute name=\"name\" /><attribute name=\"productnumber\" /><order attribute=\"name\" descending=\"false\" /></entity></fetch>"
"Malformed XML in the Paging Cookie":
pagingcookie variable = "%253ccookie%2520page%253d%25221%2522%253e%253cname%2520last%253d%2522LID%2520PMC%2520GL10%25208X10%2520D24%25205X1.5%2522%2520first%253d%2522%2526quot%253bMAC%2520TD%25202R5%252040.1%25200.5X25%25206%2526quot%253b%2520LAM%2526quot%253b%2522%2520%252f%253e%253cproductid%2520last%253d%2522%257bB73E51BB-7345-E711-80FD-C4346BAC6E90%257d%2522%2520first%253d%2522%257b9070B21C-5423-E611-80E4-5065F38A3B71%257d%2522%2520%252f%253e%253c%252fcookie%253e"
fetch using pagingcookie variable= "<fetch version=\"1.0\" output-format=\"xml-platform\" mapping=\"logical\" distinct=\"true\" page=\"2\" paging-cookie=\"%253ccookie%2520page%253d%25221%2522%253e%253cname%2520last%253d%2522LID%2520PMC%2520GL10%25208X10%2520D24%25205X1.5%2522%2520first%253d%2522%2526quot%253bMAC%2520TD%25202R5%252040.1%25200.5X25%25206%2526quot%253b%2520LAM%2526quot%253b%2522%2520%252f%253e%253cproductid%2520last%253d%2522%257bB73E51BB-7345-E711-80FD-C4346BAC6E90%257d%2522%2520first%253d%2522%257b9070B21C-5423-E611-80E4-5065F38A3B71%257d%2522%2520%252f%253e%253c%252fcookie%253e\"><entity name=\"product\"><attribute name=\"productid\" /><attribute name=\"name\" /><attribute name=\"productnumber\" /><order attribute=\"name\" descending=\"false\" /></entity></fetch>"
"Malformed XML in the Paging Cookie"
dec_uri variable= "%3ccookie%20page%3d%221%22%3e%3cname%20last%3d%22LID%20PMC%20GL10%208X10%20D24%205X1.5%22%20first%3d%22%26quot%3bMAC%20T%202R5%2040.1%200.5X25%206%26quot%3b%20LAM%26quot%3b%22%20%2f%3e%3cproductid%20last%3d%22%7bB73E51BB-7345-E711-80FD-C4346BAC6E90%7d%22%20first%3d%22%7b9070B21C-5423-E611-80E4-5065F38A3B71%7d%22%20%2f%3e%3c%2fcookie%3e"
fetch using dec_uri variable"<fetch version=\"1.0\" output-format=\"xml-platform\" mapping=\"logical\" distinct=\"true\" page=\"2\" paging-cookie=\"%3ccookie%20page%3d%221%22%3e%3cname%20last%3d%22LID%20PMC%20GL10%208X10%20D24%205X1.5%22%20first%3d%22%26quot%3bMAC%20T%202R5%2040.1%200.5X25%206%26quot%3b%20LAM%26quot%3b%22%20%2f%3e%3cproductid%20last%3d%22%7bB73E51BB-7345-E711-80FD-C4346BAC6E90%7d%22%20first%3d%22%7b9070B21C-5423-E611-80E4-5065F38A3B71%7d%22%20%2f%3e%3c%2fcookie%3e\"><entity name=\"product\"><attribute name=\"productid\" /><attribute name=\"name\" /><attribute name=\"productnumber\" /><order attribute=\"name\" descending=\"false\" /></entity></fetch>"
"No other query options are supported when a SavedQuery, UserQuery, or FetchXml parameter is provided"
dec_uri2 variable= "<cookie page="1"><name last="LI5" first="&quot;MAC6&quot; LM&quot;" /><productid last="{B73E53BB-7345-E711-80FD-C4346BAC6E90}" first="{9070B21C-5423-E611-80E4-5065F38A3B71}" /></cookie>"
fetch using dec_uri2 variable= "<fetch version=\"1.0\" output-format=\"xml-platform\" mapping=\"logical\" distinct=\"true\" page=\"2\" paging-cookie="<cookie page=\"1\"><name last=\"LID PMC GL10 8X10 D24 5X1.5\" first=\""MAC6" LM"\" /><productid last=\"{B73E51BB-7345-E811-80FD-C4346BAC6E90}\" first=\"{9070B21C-5423-E611-80E4-5065F38A3B71}\" /></cookie>\"><entity name=\"product\"><attribute name=\"productid\" /><attribute name=\"name\" /><attribute name=\"productnumber\" /><order attribute=\"name\" descending=\"false\" /></entity></fetch>"
"No other query options are supported when a SavedQuery, UserQuery, or FetchXml parameter is provided"
fetch using another test using ascii to escape= "<fetch version=\"1.0\" output-format=\"xml-platform\" mapping=\"logical\" distinct=\"true\" page=\"2\" paging-cookie=\"<cookie page=\"1\"><name last=\"LID PMC GL10 8X10 D24 5X1.5\"first=\""MAC6" LM"\"/><productid last=\"{B73A51BB-7345-E711-80FD-C4346BAC6E70}\"first=\"{9070B21C-5423-E611-80E4-5066F38A3B21}\"/></cookie>\"><entity name=\"product\"><attribute name=\"productid\" /><attribute name=\"name\" /><attribute name=\"productnumber\" /><order attribute=\"name\" descending=\"false\" /></entity></fetch>"
That's the function that make the fetch
SdkWebAPI.getFetchXml = function (entitySetName, fetchXml, successCallback, errorCallback, passthroughObj, passthroughObj1) {
if (isNullOrUndefined(entitySetName)) {
throw new Error("SdkWebAPI.getFetchXml entitySetName parameter must not be null or undefined.");
}
if (!isString(fetchXml)) {
throw new Error("SdkWebAPI.getFetchXml fetchXml parameter must be a string.");
}
if (!isFunctionOrNullOrUndefined(successCallback)) {
throw new Error("SdkWebAPI.getFetchXml successCallback parameter must be a function or null.");
}
if (!isFunctionOrNullOrUndefined(errorCallback)) {
throw new Error("SdkWebAPI.getFetchXml errorCallback parameter must be a function or null.");
}
var async = !!successCallback;
fetchXml = fetchXml.replace(/\"/g, "'");
var url = getWebAPIPath() + entitySetName + "?fetchXml=" + fetchXml;
var req = new XMLHttpRequest();
req.open("GET", encodeURI(url), async);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.setRequestHeader("Prefer", "odata.include-annotations=*");
if (async) {
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
switch (this.status) {
case 200:
if (successCallback) {
var hasMoreRecords = false;
var pagingCookie = undefined;
var val = JSON.parse(this.response);
if (val["@Microsoft.Dynamics.CRM.fetchxmlpagingcookie"] != null) {
hasMoreRecords = true;
pagingCookie = val["@Microsoft.Dynamics.CRM.fetchxmlpagingcookie"];
}
successCallback(val.value, hasMoreRecords, pagingCookie, passthroughObj, passthroughObj1);
}
break;
default:
if (errorCallback)
errorCallback(SdkWebAPI.errorHandler(this), "Get FetchXml");
break;
}
}
};
}
req.send();
if (!async) {
var fetchResult = { PagingCookie: null, HasMoreRecords: false, Value: null };
if (req.response) {
try {
var val = JSON.parse(req.response);
fetchResult.Value = val.value;
if (val["@Microsoft.Dynamics.CRM.fetchxmlpagingcookie"] != null) {
fetchResult.HasMoreRecords = true;
fetchResult.PagingCookie = val["@Microsoft.Dynamics.CRM.fetchxmlpagingcookie"];
}
} catch (e) {
}
}
return fetchResult;
}
}
I'm really getting crazy here with that thing. I really do not know why is it working at XRMToolbox but not on javascript. Some tips? maybe try to use SOAP? other encode/decode method? Get out with the circus and be happy as a clown?
In one of the links i sent the author says:
"Note - The cookie value needs to be decoded, and special characters needs to be replaced with supported versions of the same in order to make a valid OData call, otherwise you will get 500 Internal Server Error, and error response as Invalid XML, or Malformed XML in the Paging Cookie, or An item with the same key has already been added."
I tried a lot of different methods and it's not working...
Thank you all in advance