SOAP and REST endpoints

Microsoft Dynamics CRM 2011 has two services available, and each service provides specific strengths when it comes to client-side programming. SOAP endpoint is recommended for retrieving metadata, assigning records and executing messages programmatically. REST endpoint is recommended for creating, retrieving, updating, and deleting records. It is also recommended for associating and disassociating records. Both of these web services rely on the authentication provided by CRM; the web services are not accessible outside of the application. You can use the web services within JScript libraries, Web Pages, and Silverlight Controls that are stored in Web Resources.

SOAP endpoint

The SOAP endpoint provides access to all of the messages defined in the Organization service. There is no strong type support, and only the types defined within the WSDL will be returned.

The SOAP endpoint uses the Organization service, and the authentication is provided by the application. You can use the SOAP endpoint for Web Resources with JScript libraries or by using Microsoft Silverlight.

Using the SOAP endpoint with JScript

To use the SOAP endpoint with JScript, you need to use XmlHttpRequest to POST requests to the service. The body of the request must contain the XML appropriate for the message that you are using. You must also parse the XML returned in a response. With XmlHttpRequest it is possible to make synchronous requests. However, it is highly recommended to always use asynchronous requests. Because manually configuring each request is very time-consuming, it is expected that you will reuse existing libraries or create your own.

The following JScript sample shows how you can use the SOAP endpoint to assign records in Microsoft Dynamics CRM 2011:

if (typeof (SDK) == "undefined")
{ SDK = { __namespace: true }; }
SDK.SOAPSamples = {
  _getServerUrl: function () {
  var OrgServicePath = "/XRMServices/2011/Organization.svc/web";
  var serverUrl = ";
  if (typeof GetGlobalContext == "function") {
    var context = GetGlobalContext();
    serverUrl = context.getServerUrl();  }
  else {
    if (typeof Xrm.Page.context == "object") {
      serverUrl = Xrm.Page.context.getServerUrl();}
    else
    { throw new Error("Unable to access the server URL"); }
  }
  if (serverUrl.match(//$/)) {
    serverUrl = serverUrl.substring(0, serverUrl.length - 1);}
 return serverUrl + OrgServicePath;
},
  assignRequest: function (Assignee, Target, Type, successCallback, errorCallback) {
  var request = "<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">";
  request += "<s:Body>";
  request += "<Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services";
  request += " xmlns:i="http://www.w3.org/2001/XMLSchema-instance">";
  request += <request i:type="b:AssignRequest";
  request += " xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts";
  request += " xmlns:b="http://schemas.microsoft.com/crm/2011/Contracts">";
  request += "<a:Parameters xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic">";
  request += "<a:KeyValuePairOfstringanyType>";
  request += "<c:key>Target</c:key>";
  request += "<c:value i:type="a:EntityReference">";
  request += "<a:Id>" + Target + "</a:Id>";
  request += "<a:LogicalName>" + Type + "</a:LogicalName>";
  request += "<a:Name i:nil="true" />";
  request += "</c:value>";
  request += "</a:KeyValuePairOfstringanyType>";
  request += "<a:KeyValuePairOfstringanyType>";
  request += "<c:key>Assignee</c:key>";
  request += "<c:value i:type="a:EntityReference">";
  request += "<a:Id>" + Assignee + "</a:Id>";
  request += "<a:LogicalName>systemuser</a:LogicalName>";
  request += "<a:Name i:nil="true" />";
  request += "</c:value>";
  request += "</a:KeyValuePairOfstringanyType>";
  request += "</a:Parameters>";
  request += "<a:RequestId i:nil="true" />";
  request += "<a:RequestName>Assign</a:RequestName>";
  request += "</request>";
  request += "</Execute>";
  request += "</s:Body>";
  request += "</s:Envelope>";

  var req = new XMLHttpRequest();
  req.open("POST", SDK.SOAPSamples._getServerUrl(), true)
  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/Execute");
  req.onreadystatechange = function () { SDK.SOAPSamples.assignResponse(req, successCallback, errorCallback); };
  req.send(request); },
  assignResponse: function (req, successCallback, errorCallback) {
    if (req.readyState == 4) {
      if (req.status == 200) {
        if (successCallback != null)
        { successCallback(); }
      }
      else {
        errorCallback(SDK.SOAPSamples._getError(req.responseXML));}
      }
    },
    _getError: function (faultXml) {
      var errorMessage = "Unknown Error (Unable to parse the fault)";
      if (typeof faultXml == "object") {
        try {
          var bodyNode = faultXml.firstChild.firstChild;
          for (var i = 0; i < bodyNode.childNodes.length; i++) {
            var node = bodyNode.childNodes[i];

            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;
                  break; }
              }
              break;
            }
          }
        }
        catch (e) { };
      }
      return new Error(errorMessage);
    },
  __namespace: true
};

Using the SOAP endpoint with Silverlight

To use the SOAP endpoint with Silverlight, you need to adhere to the following guidelines after your project is created:

  1. Add a service reference to the Organization service.

    Note

    Note: The URL of the service is located on the Developer Resources page of Microsoft Dynamics CRM 2011. In the Settings area, select Customizations, and then select Developer Resources.

  2. Add some additional files to your solution, and manually modify the Reference.cs file that is generated when you add the service reference.
  3. Write code using asynchronous methods.
  4. Use the late binding syntax, because strong types are not available.

REST endpoint

REST is the abbreviation for Representational State Transfer. You can use the REST endpoint to execute HTTP requests by using a service that is based on a URI. REST works the way the Internet works. You interact with resources by using HTTP verbs such as GET, POST, MERGE, and DELETE. Various libraries can be used to process the HTTP requests and responses. REST allows for synchronous and asynchronous processing of operations. The capability to perform asynchronous operations makes REST a good fit for Silverlight clients.

Microsoft Dynamics CRM 2011 uses the WCF Data Services framework to provide an OData endpoint that is a REST-based data service. The endpoint is called the Organization Data Service. The Organization Data Service root URI is:

[Your Organization Root URL]/xrmservices/2011/organizationdata.svc

To provide a consistent set of URIs that correspond to the entities used in Microsoft Dynamics CRM, an Entity Data Model organizes the form of records of "entity types" and the ones associated between them. The Entity Data Model in OData Service Metadata document is available at:

[Your Organization Root URL]/xrmservices/2011/organizationdata.svc/$metadata

Because the REST endpoint cannot perform the Execute operation, it is the recommended web service for tasks that involve creating, retrieving, updating, and deleting records.

Let's take a look at a sample to create, retrieve, update, and delete records using the REST endpoint.

The following code demonstrates how to use the REST endpoint to create a Crew Member in the ACM system:

function createContactRecord(firstName, lastName) {
  showMessage("createContactRecord function START");
  var Contact = new Object();
  Contact.FirstName = firstName;
  Contact.LastName = lastName;
  var jsonContact = window.JSON.stringify(Contact);

  var createContactReq = new XMLHttpRequest();
  createContactReq.open("POST", ODataPath + "/ContactSet", true);
  createContactReq.setRequestHeader("Accept", "application/json");
  createContactReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
  createContactReq.onreadystatechange = function () {
    createContactReqCallBack(this);
  };
  createContactReq.send(jsonContact);
  showMessage("createContactRecord function END");
}

function createContactReqCallBack(createContactReq) {
  if (createContactReq.readyState == 4 /* complete */) {
    if (createContactReq.status == 201) {
    //Success
    var newContact = JSON.parse(createContactReq.responseText).d;
    showMessage("ACTION: Created new Contact id:{" +       newContact.ContactId + "}.");

    //NEXT STEP: Retrieve the Contact
    retrieveContactRecord(newContact.ContactId);
    showMessage("createContactReqCallBack function success END");
    }
    else {
      //Failure
      errorHandler(createContactReq);
      showMessage("createContactReqCallBack function failure END");
    }
  }
};

The following code demonstrates how to use the REST endpoint to retrieve a Crew Member in the ACM system:

function retrieveContactRecord(Id) {
  showMessage("retrieveContactRecord function START");

  var retrieveContactReq = new XMLHttpRequest();
  retrieveContactReq.open("GET", ODataPath + "/ContactSet(guid'" + Id + "')", true);
  retrieveContactReq.setRequestHeader("Accept", "application/json");
  retrieveContactReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
  retrieveContactReq.onreadystatechange = function () {
  retrieveContactReqCallBack(this);
  };
  retrieveContactReq.send();
  showMessage("retrieveContactRecord function END.");
}

function retrieveContactReqCallBack(retrieveContactReq) {
  if (retrieveContactReq.readyState == 4 /* complete */) {
    if (retrieveContactReq.status == 200) {
   //Success
    var retrievedContact = JSON.parse(retrieveContactReq.responseText).d;
    showMessage("ACTION: Retrieved Contact Name = "" + retrievedContact.FullName + "", ContactId = {" + retrievedContact.ContactId + "}");

    //NEXT STEP: Update the Contact
    updateContactRecord(retrievedContact.ContactId);
    showMessage("retrieveContactReqCallBack function success END");
    }
    else {
     //Failure
     errorHandler(retrieveContactReq);
     showMessage("retrieveContactReqCallBack function failure END");
    }
  }
}

The following code demonstrates how to use the REST endpoint to update a Crew Member in the ACM system:

function updateContactRecord(Id) {
  showMessage("updateContactRecord function START");
  var updateContactReq = new XMLHttpRequest();
  var changes = new Object();
  changes.FirstName = "Darren";
  changes.FirstName = "Liu";
  changes.Telephone1 = "555-0123";
  changes.EMailAddress1 = "[email protected]";

  updateContactReq.open("POST", ODataPath + "/ContactSet(guid'" + Id + "')", true);
  updateContactReq.setRequestHeader("Accept", "application/json");
  updateContactReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
  updateContactReq.setRequestHeader("X-HTTP-Method", "MERGE");
  updateContactReq.onreadystatechange = function () {
    updateContactReqCallBack(this, Id);
  };
  updateContactReq.send(JSON.stringify(changes));
  showMessage("updateContactRecord function END.");
}

function updateContactReqCallBack(updateContactReq, Id) {
  if (updateContactReq.readyState == 4 /* complete */) {
    //There appears to be an issue where IE maps the 204 statusto 1223 when no content is returned.
    if (updateContactReq.status == 204 || updateContactReq.status == 1223) {
      //Success
      showMessage("ACTION: Updated Contact data.");

      //NEXT STEP: Delete the Contact
      deleteContactRecord(Id);
      showMessage("updateContactReqCallBack function success END");
    }
    else {
      //Failure
      errorHandler(updateContactReq);
      showMessage("updateContactReqCallBack function failure END");
    }
  }
}

The following code demonstrates how to use the REST endpoint to delete a Crew Member in the ACM system:

function deleteContactReqCallBack(deleteContactReq) {
  if (deleteContactReq.readyState == 4 /* complete */) {
    //There appears to be an issue where IE maps the 204 status to 1223 when no content is returned.
    if (deleteContactReq.status == 204 || deleteContactReq.status == 1223) {
      //Success
      showMessage("ACTION: The Contact record was deleted.");
      showMessage("deleteContactReqCallBack function success END");
    }
    else {
      //Failure
      errorHandler(deleteContactReq);
      showMessage("deleteContactReqCallBack function failure END");
    }
  }
}

There are many other things that you can do with the SOAP and REST Endpoints. The new programming model also provides developers with other functionality for client-side programming. The new features allow all of us to take CRM customization to the next level.

Note

There are more sample codes in the Microsoft Dynamics CRM 2011 Software Development Kit(SDK). To download the Microsoft Dynamics CRM 2011 SDK, visit the Microsoft Download Center at http://www.microsoft.com/download/en/details.aspx?id=24004.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.145.191.134