web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Microsoft Dynamics CRM (Archived)

Paging Cookie not working on JS

(0) ShareShare
ReportReport
Posted on by 67

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('<', '&lt;')
                        dec_uri2 = dec_uri2.replaceAll('>', '&gt;')
                        dec_uri2 = dec_uri2.replaceAll('&quot;', '&amp;quot;')
                        dec_uri2 = dec_uri2.replaceAll('\"', '&quot;')
                        
                        /*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="&lt;cookie page=&quot;1&quot;&gt;&lt;name last=&quot;LID 5X1.5&quot; first=&quot;&amp;quot;MAC6&amp;quot; LM&amp;quot;&quot; /&gt;&lt;productid last=&quot;{B73E51BC-7355-E711-80FD-C4346BAC6E90}&quot; first=&quot;{9150B21C-5423-E611-80E4-5065F38A3B71}&quot; /&gt;&lt;/cookie&gt;" >
    <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= "&lt;cookie page=&quot;1&quot;&gt;&lt;name last=&quot;LI5&quot; first=&quot;&amp;quot;MAC6&amp;quot; LM&amp;quot;&quot; /&gt;&lt;productid last=&quot;{B73E53BB-7345-E711-80FD-C4346BAC6E90}&quot; first=&quot;{9070B21C-5423-E611-80E4-5065F38A3B71}&quot; /&gt;&lt;/cookie&gt;"
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=\"&quot;MAC6&quot; LM&quot;\" /><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=\"&#60;cookie page&#61;\"1\"&#62;&#60;name last&#61;\"LID PMC GL10 8X10 D24 5X1.5\"first&#61;\"&#34;MAC6&#34; LM&#34;\"/&#62;&#60;productid last&#61;\"{B73A51BB-7345-E711-80FD-C4346BAC6E70}\"first&#61;\"{9070B21C-5423-E611-80E4-5066F38A3B21}\"/&#62;&#60;/cookie&#62;\"><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

*This post is locked for comments

I have the same question (0)
  • Suggested answer
    gdas Profile Picture
    50,091 Moderator on at

    Hi,

    Please have a look below article-

    community.dynamics.com/.../issue-faces-in-retrieving-5000-records-using-web-api

  • Sreevalli Profile Picture
    3,256 on at

    Hi,

    Use below five replacement to the cookie XML

    1. &lt; (<)
    2. &amp; (&)
    3. &gt; (>)
    4. &quot; (")
    5. &apos; (') -- not needed

    so the replacements will follow as below (from your 1st code snippet)

    /*double decode and format. */
    var dec_uri = decodeURIComponent(pagingcookie)
    var dec_uri2 = decodeURIComponent(dec_uri)
    dec_uri2 = dec_uri2.replaceAll('<', '&lt;')
    dec_uri2 = dec_uri2.replaceAll('>', '&gt;')
    dec_uri2 = dec_uri2.replaceAll('&', '&amp;')
    dec_uri2 = dec_uri2.replaceAll('\"', '&quot;')
    
    /*Format the old fetch */
    fetch = fetch.replace('page=\"' + count + '\"', 'page=\"' + ++count + '\" paging-cookie=\"' + dec_uri2 + '\"')
                             

    If you are much comfortable with C# paging then try to generate SOAP query with SOAPLogger(<your path>\SDK\SampleCode\CS\Client\SOAPLogger)

    help link - https://www.powerobjects.com/2012/05/23/microsoft-dynamics-crm-soap-logger-a-tool-that-can-greatly-simplify-writing-http-requests/ 

  • Feminho Diniz Profile Picture
    67 on at

    Hi, Sreevalli Balleda. I tried as you said and got an error

    errojs.png

  • Sreevalli Profile Picture
    3,256 on at

    Could you share the final page cookie after replacements from watch.

  • Feminho Diniz Profile Picture
    67 on at

    "<fetch version=\"1.0\" output-format=\"xml-platform\" mapping=\"logical\" distinct=\"true\" page=\"2\" paging-cookie=\"&lt;cookie page="1"&gt;&lt;name last="LID PMC GL10 8X10 D24 4X1.5" first="&quot;MACDRAIN TD 2R5 40.1 0.5X25 6&quot; LAM&quot;" /&gt;&lt;productid last="{71D9D9B9-7345-E711-80FB-C4346BACBEF8}" first="{9070B21C-5423-E611-80E4-5065F38A3B71}" /&gt;&lt;/cookie&gt;\"><entity name=\"product\"><attribute name=\"productid\" /><attribute name=\"name\" /><attribute name=\"productnumber\" /><order attribute=\"name\" descending=\"false\" /></entity></fetch>"

  • Feminho Diniz Profile Picture
    67 on at

    I tried with this code:

                           /*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('\"', '"')

                           dec_uri2 = dec_uri2.replace(/&/g, '&amp;'); //The code that i found on the link

                           /*Format the old fetch */

                           fetch = fetch.replace('page=\"' + count +'\"', 'page=\"'+ ++count + '\" paging-cookie=\"' + dec_uri2 + '\"')

    The response was:

    ErrorCode: "0x0"

    ​​

    ExceptionMessage: "An item with the same key has already been added."

    ​​

    ExceptionType: "System.ArgumentException"

    ​​

    Message: "An item with the same key has already been added."

    ​​

    StackTrace: " at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)\r\n at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)\r\n at System.Linq.Enumerable.ToDictionary[TSource,TKey,TElement](IEnumerable`1 source, Func`2 keySelector, Func`2 elementSelector, IEqualityComparer`1 comparer)\r\n at Microsoft.Crm.Extensibility.ODataV4.Edm.EdmExtensions.QueryParameterDictionary(HttpRequestMessage request)\r\n at Microsoft.Crm.Extensibility.OData.CrmODataHeaders.ProcessVersioningQueryParameters()\r\n at Microsoft.Crm.Extensibility.OData.CrmODataHeaders..ctor(HttpRequestMessage request)\r\n at Microsoft.Crm.Extensibility.ODataV4.Edm.EdmExtensions.GetCrmODataRequestHeader(HttpRequestMessage request)\r\n at Microsoft.Crm.Extensibility.ODataV4.Routing.CrmODataRoutingConvention.SelectControllerImplementation(ODataPath odataPath, HttpRequestMessage request)\r\n at Microsoft.PowerApps.CoreFramework.ActivityLoggerExtensions.Execute[TResult](ILogger logger, EventId eventId, ActivityType activityType, Func`1 func, IEnumerable`1 additionalCustomProperties)\r\n at Microsoft.Xrm.Telemetry.XrmTelemetryExtensions.Execute[TResult](ILogger logger, XrmTelemetryActivityType activityType, Func`1 func)\r\n at System.Web.OData.Routing.ODataPathRouteConstraint.SelectControllerName(ODataPath path, HttpRequestMessage request)\r\n at System.Web.OData.Routing.ODataPathRouteConstraint.Match(HttpRequestMessage request, IHttpRoute route, String parameterName, IDictionary`2 values, HttpRouteDirection routeDirection)\r\n at System.Web.Http.Routing.HttpRoute.ProcessConstraint(HttpRequestMessage request, Object constraint, String parameterName, HttpRouteValueDictionary values, HttpRouteDirection routeDirection)\r\n at System.Web.Http.Routing.HttpRoute.ProcessConstraints(HttpRequestMessage request, HttpRouteValueDictionary values, HttpRouteDirection routeDirection)\r\n at System.Web.Http.Routing.HttpRoute.GetRouteData(String virtualPathRoot, HttpRequestMessage request)\r\n at System.Web.Http.WebHost.Routing.HttpWebRoute.GetRouteData(HttpContextBase httpContext)"

    ​​

  • Verified answer
    Feminho Diniz Profile Picture
    67 on at

    At the end the problem was resolved using a different method to retrieve the records. I guess the method I was using didn't accepted the encode used on my paging cookie. I create the paging cookie by myself and the final code was more and less like that

    for (i = 1; i <= count; i++) {
    
                                  if (i == 1)
                                                var fetch = "<fetch mapping ='logical' distinct= 'true' >";
                                  else
                                                var fetch = "<fetch page='"+ i +"' paging-cookie='&lt;cookie page=&quot;" + (i-1) + "&quot;&gt;&lt;productid last=&quot;" + lastResult +"&quot; first=&quot;" + firstResult + "&quot; /&gt;&lt;/cookie&gt;'>";
                                  fetch += "<entity name ='product'>";
                                  for (var k = 0; k < attArray.length; k++) {
                                                fetch += '<attribute name="' + attArray[k] + '" />' 
                                  }
                                  fetch += "</entity>";
                                  fetch += "</fetch>";
                                  //var result = SdkWebAPI.getFetchXml("products", fetch)//XHUB.SOAP.Fetch(fetch);  
                                  fetch = fetch.replaceAll('\"', "'")
                                  fetch = "?fetchXml=" + encodeURIComponent(fetch);
    
                                  window.parent.Xrm.WebApi.retrieveMultipleRecords("product", fetch).then(
                                    function success(result) {
                                        ;
                                        if (i != count) {
                                                lastResult = result.entities[4999].productid;
                                                firstResult = result.entities[0].productid;
                                            }
                                                            
                                            for (j = 0; j < result.entities.length; j++) {
                                                resultTotal.push(result.entities[j]);
                                            }
                                        // perform additional operations on retrieved records
                                    },
                                    function (error) {
                                        console.log(error.message);
                                        // handle error conditions
                                    });
                            
                                  
                                debugger;
                   }


Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > 🔒一 Microsoft Dynamics CRM (Archived)

#1
SA-08121319-0 Profile Picture

SA-08121319-0 4

#1
Calum MacFarlane Profile Picture

Calum MacFarlane 4

#3
Alex Fun Wei Jie Profile Picture

Alex Fun Wei Jie 2

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans