How to execute RetrieveMultiple request from Javascript

Frequently in our CRM projects we need to retrieve multiple records for some entity based on some conditions. We have the OrganizationDataService to achieve that. However with the OrganizationDataService we cannot write complex joins and many other stuffs what we can achieve through fetchxml. What if we could utilise the the power of fetchxml from our client side. Well that not difficult at all. Here I would show you how to perform a retrievemultiple request from client side.

Below is the complete code to do the same. Please note that while passing your fetch xml as the request argument, you need to perform HTML encoding of the fetchstring. Otherwise you would get a serialization error when the request is being executed.

var fetchString = [“<fetch version=’1.0′ output-format=’xml-platform’ mapping=’logical’ distinct=’true’>”,
“ <entity name=’systemuser’>”,
    “<filter type=’and’>”,
      “<condition attribute=’isdisabled’ operator=’eq’ value=’0′ />”,
      “<condition attribute=’accessmode’ operator=’ne’ value=’3′ />”,
    “</filter>”,
  “</entity>”,
”</fetch>”].join(“”);

 

retrieveMultiple(fetchString);

function retrieveMultiple(query) {
        var request = getRetrieveMultipleRequestBody(htmlEncode(query));

        return executeRequest(request, false);
    },

function getRetrieveMultipleRequestBody(fetch) {
        var xml = [‘<s:Envelope xmlns:s=”
http://schemas.xmlsoap.org/soap/envelope/”>’,
                  ‘<s:Body>’,
                    ‘<RetrieveMultiple xmlns=”
http://schemas.microsoft.com/xrm/2011/Contracts/Services” xmlns:i=”http://www.w3.org/2001/XMLSchema-instance”>’,
                      ‘<query i:type=”a:FetchExpression” xmlns:a=”
http://schemas.microsoft.com/xrm/2011/Contracts”>’,
                        ‘<a:Query>’,
                            fetch,
                        ‘</a:Query>’,
                      ‘</query>’,
                    ‘</RetrieveMultiple>’,
                  ‘</s:Body>’,
                ‘</s:Envelope>’].join(”);

        return xml;
    };

 

function htmlEncode(str) {
        return String(str)
            .replace(/&/g, ‘&amp;’)
            .replace(/”/g, ‘&quot;’)
            .replace(/’/g, ‘'’)
            .replace(/</g, ‘&lt;’)
            .replace(/>/g, ‘&gt;’);
    },

    // Private function that creates a return object for synchronous calls
function   _getReturnObject(returnValue, successFlag) {
        return {
            Success: successFlag,
            Value: returnValue
        };
    },

    // Private function to parse the error xml.
   function  _getError: function (faultXml) {
        var errorMessage = “Unknown Error (Unable to parse the fault)”;
        if (typeof faultXml == “object”) {
            try {
                var bodyNode = faultXml.firstChild.firstChild;
                //Retrieve the fault node
                for (var i = 0; i < bodyNode.childNodes.length; i++) {
                    var node = bodyNode.childNodes[i];

                    //NOTE: This comparison does not handle the case where the XML namespace changes
                    if (“s:Fault” == node.nodeName) {
                        for (var j = 0; j < node.childNodes.length; j++) {
                            var faultStringNode = node.childNodes[j];
                            if (“faultstring” == faultStringNode.nodeName) {
                                errorMessage = faultStringNode.text || faultStringNode.textContent;
                                break;
                            }
                        }
                        break;
                    }
                }
            }
            catch (e) { }
        }
        return new Error(errorMessage);
    }

 

function executeRequest(request, isAsync) {
        var req = window.ActiveXObject != undefined ? new ActiveXObject(“Microsoft.XMLHTTP”) : new XMLHttpRequest();
        var req = new XMLHttpRequest();
        req.open(“POST”, Xrm.Page.context.getClientUrl() + “/XRMServices/2011/Organization.svc/web”, isAsync);

        // Responses will return XML. It isn’t possible to return JSON.
        req.setRequestHeader(“Accept”, “application/xml, text/xml, */*”);
        req.setRequestHeader(“Content-Type”, “text/xml; charset=utf-8”);
        req.setRequestHeader(“SOAPAction”, “
http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/RetrieveMultiple”);
        req.send(request);

        if (req.status == 200) {
            return _getReturnObject(req.responseXML, true);
        }
        else {
            return _getReturnObject(_getError(req.responseXML), false);
        }
    }

 

Hope this helps!


Advertisements

Author: Debajit

I am a Dynamics CRM Most Valuable Professional (MVP) with 10 years of experience in Microsoft .NET Technologies and 7 years of dedicated experience in Microsoft Dynamics CRM. I have worked with companies like Microsoft, SanDisk, PwC, TMF Group and have extensive experience of implementing complex CRM solutions from both offshore and client side. Currently the face of XrmForYou.com with significant experience in delivering corporate training on Dynamics CRM and have already delivered multiple projects to client through XrmForYou.com Author of multiple tools on codeplex including the 'Role Based Views' and 'CRM-Sharepoint Metadata manager & Attachment Extractor' which are available for commercial use under XrmForYou.com For consulting/ training, drop me a note at info@xrmforyou.com or visit our website www.xrmforyou.com

1 thought on “How to execute RetrieveMultiple request from Javascript”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s