03 April 2013

Using The CRM 2011 SOAP Endpoint

When we retrieve data from CRM 2011 through JavaScript more often than not we use the REST endpoints but there are times when you may decide that the SOAP endpoint is going to be a better tool for the job. This article isn't going to dictate which endpoint you use, there is an article on MSDN which outlines the benefits of each: Use Web Service Data in Web Resources (REST and SOAP Endpoint).

If you want to get at CRM data through the SOAP endpoint then here some steps that will get you to where you want to be:

1. The SDK has a code sample called SOAPLogger, after downloading the SDK navigate to samplecode\cs\client\soaplogger\ and open the project in Visual Studio
2. We now need to add some code that we'll use to generate the SOAP envelope. In this sample it will retrieve a contact record returning the first name, last name, and email address. Open up SOAPLogger.cs and add the following to the Run Method:

Guid contactId = new Guid("[A Valid GUID goes here]");

RetrieveRequest retrieveContact = new RetrieveRequest();
retrieveContact.ColumnSet = new ColumnSet(new string[] { "firstname", "lastname", "emailaddress1" });
retrieveContact.Target = new EntityReference("contact", contactId);

slos.Execute(retrieveContact);


3. Go ahead and run the project, a command prompt appears and you'll need to provide the connection information to the CRM server you want to connect to. After the code has executed you're prompted to "Press (Enter) to exit."

4. A text file has been created in the execution folder called "output.txt", open this with notepad.

5. We are interested in the HTTP REQUEST section, specifically the soap envelope, which we'll copy (see highlighted text in screenshot):


6. Now we're ready to write some JavaScript, the request variable is going to contain the SOAP envelope that we copied in the previous step:
var serverUrl = "[CRM Server Url]";

var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", serverUrl() + "/XRMServices/2011/Organization.svc/web", false);
xmlhttp.setRequestHeader("Accept", "application/xml, text/xml, */*");
xmlhttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
xmlhttp.setRequestHeader("SOAPAction", "http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/Execute");

var request = "";
request += '';
request += '  ';
request += '    ';
request += '      ';
request += '        ';
request += '          ';
request += '            Target';
request += '            ';
request += '              e183560d-2680-e211-bc33-005056ba9f90';
request += '              contact';
request += '              ';
request += '            ';
request += '          ';
request += '          ';
request += '            ColumnSet';
request += '            ';
request += '              false';
request += '              ';
request += '                firstname';
request += '                lastname';
request += '                emailaddress1';
request += '              ';
request += '            ';
request += '          ';
request += '        ';
request += '        ';
request += '        Retrieve';
request += '      ';
request += '    ';
request += '  ';
request += '';

xmlhttp.send(request);

7. xmlhttp.responseXML.xml is going to contain the response XML from the web service call. To make like easier I've written a method that you can pass the XML to, along with the field name, which will return the value (e.g. GetResponse(xmlhttp.responseXML.xml, "firstname"):

GetResponse = function (responseXML, attributename)
{
    var returnValue = "";

    try
    {
  var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
        xmlDoc.async = "false";
        xmlDoc.loadXML(responseXML);
        
        var x = xmlDoc.getElementsByTagName("a:KeyValuePairOfstringanyType");

        for (i = 0; i < x.length; i++)
        {
            if (x[i].childNodes[0].text == attributename)
            {
                returnValue = x[i].childNodes[1].text;
                break;
            }
        }
    }
    catch (e)
    {
        returnValue = "";
    }
    return returnValue;
}



No comments:

Post a Comment