{Dynamics CRM} 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

One thought on “{Dynamics CRM} 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 )

Google+ photo

You are commenting using your Google+ 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 )

Connecting to %s