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, ‘&’)
.replace(/”/g, ‘"’)
.replace(/’/g, ”’)
.replace(/</g, ‘<’)
.replace(/>/g, ‘>’);
},
// 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;
}
&nb
sp; }
}
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!
Discover more from Debajit's Power Apps & Dynamics 365 Blog
Subscribe to get the latest posts sent to your email.
Pingback: Call plugin from Javascript in Microsoft Dynamics CRM. | Debajit's Dynamic CRM Blog