Calling “CRM” Web services using JScript

Since I wrote the post about calling "any" web service from CRM forms (BTW, that is my most viewed post to date!), folks have written to me and asked "what the heck, what about calling “CRM” web services, hello"?

Calling CRM web services from JScript is not the best programming experience that you could imagine, mostly because it is not much fun using strongly typed classes in Jscript code (Atlas solves that problem to a great degree, more on this later) whereas you do get a great developer experience inside Visual Studio with strongly typed classes.

So there are two options to call CRM web services from CRM forms (or from any html/aspx pages using JScript) 1) use a intermediate proxy web service with a simple interface that masks the complexy of strongly typed classes. Such web service can have complex code and calls CRM web services using our WSDL. This approach may work for many of your scenarios where performance is not as critical as developer experience 2) call CRM web services directly from CRM form using SOAP messages (there is a third option to use Atlas. Michael who is one of our dev leads and I are still thinking about the best way to get that to work, stay tuned). This approach is less developer friendly to work with since you have to create a SOAP message in JScript, send it to the CRM server and parse the returned XML to get the data that you need, but it should be faster than calling teh intermediate service. Here is a sample to show you how to do this using JScript and POST.

This sample directly calls CRM web service RetrieveMultiple method and passes a QueryByAttribute object. The query condition is to retrieve all the accounts that are in the state of Washington (address1_stateorprovince = WA).

First thing I did was to enable tracing and capture the SOAP message for RetrieveMultiple passing in a QueryByAttribute. The tracing file includes both requests and responses. Next, I added the SOAP request string to my POST request on the Jscript code. I post the SOAP message to CRM web service and get the results back in xml. Then I parse the xml to extract the data that I am interested in, in this case a list of account names. Finally I write the account names on the html page that i am calling the web service from. The sample is written for a standalone html page but you can easily cut and paste the code into Onload, OnSave or OnChange event of any CRM forms.

Make sure you add your server name where it says below.

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">

<title>Access CRM Web Services</title>

<SCRIPT language="JavaScript">

//Call CRM web services directly

function AccessCRMWebServices()

{

var serverUrl = "http:// <ADD your Server name here> /mscrmservices/2006";

var xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");

alert(serverUrl+ "/crmservice.asmx");

xmlhttp.open("POST", serverUrl + "/crmservice.asmx", false);

xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8")

xmlhttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/crm/2006/WebServices/RetrieveMultiple")

xmlhttp.send("<?xml version='1.0' encoding='utf-8'?>"+"\n\n"+"<soap:Envelope"+

' xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"'+

' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'+

' xmlns:xsd="http://www.w3.org/2001/XMLSchema">'+

' <soap:Body>' +

' <query xmlns:q1="http://schemas.microsoft.com/crm/2006/Query" xsi:type="q1:QueryByAttribute" xmlns="http://schemas.microsoft.com/crm/2006/WebServices">'+

' <q1:EntityName>account</q1:EntityName>'+

' <q1:ColumnSet xsi:type="q1:ColumnSet">'+

' <q1:Attributes>'+

' <q1:Attribute>name</q1:Attribute>'+

' <q1:Attribute>address1_stateorprovince</q1:Attribute>'+

' </q1:Attributes>'+

' </q1:ColumnSet>'+

' <q1:Attributes>'+

' <q1:Attribute>address1_stateorprovince</q1:Attribute>'+

' </q1:Attributes>'+

' <q1:Values>'+

' <q1:Value xsi:type="xsd:string">WA</q1:Value>'+

' </q1:Values>'+

' </query>'+

' </soap:Body>'+

' </soap:Envelope>')

var result = xmlhttp.responseXML.xml;

//Separate the BusinessEntities XML tag

var BEs= result.split("<BusinessEntities>");

//Separate the BusinessEntity XML tag

var BE = BEs[1].split("<BusinessEntity");

//Walk through each Business Entity tag and extract account names

for (i = 0; i < BE.length; i++)

{

first = BE[i].indexOf("<name>")+6;

second = BE[i].indexOf("</name>");

document.writeln(BE[i].substring(first,second) + "<BR>");

}

}

//Simply call the method when the page is loaded

AccessCRMWebServices() ;

</SCRIPT>

</head>

<body>

</body>

</html>