Friday 3 October 2014

Sdk.Soap.js

 

In this post, I would like to share details about the Sdk.Soap.js library and sample code for some of the very commonly used messages. At present this library supports 202 messages. It helps in writing easy and quick SOAP call(s) in web resources and reduces the size of the source code a lot. Also, these SOAP call(s) are easy in understanding and reading. In Dynamics CRM, we can write both REST and SOAP calls. However, The REST calls have its’ own limitations. Please refer following URL to know more about oData endpoint limitations.

http://ankit.inkeysolutions.com/2012/03/limitations-of-odata-endpoint-in-crm.html

To overcome these problems it is good to use quick SOAP calls with the help of the Sdk.Soap.js

Note: This library does not provide code to authenticate.

The Sdk.soap.js library comprises of 4 types of namespaces:

1. Sdk.Async

2. Sdk.Sync

3. Sdk.jQ

4. Sdk.Q

The first two namespaces can be used directly at form events like form load, form save, attribute on change etc. Their names itself help us to realise which namespace needs to be used for asynchronous operation(s) and synchronous operation(s). The last two should be used in HTML web resources. Additionally, you can reduce the size of this library by removing the unrequired namespaces from the Sdk.Soap.vsdoc.js file.

In this blog I would like to cover the sample code for the most common messages of the first namespace i.e. Sdk.Async

Examples:

· Create

function AsyncCreateRecord() {
  var contact = new Sdk.Entity("contact");
  var userID = new Sdk.EntityReference("systemuser", "GUID ");  //Use the GUID value of user record
  contact.addAttribute(new Sdk.String("lastname", "Async record Last Name"));
  contact.addAttribute(new Sdk.Lookup("ownerid", userID));
  Sdk.Async.create(contact, function (newlyCreatedRecordID) { alert("Async Contact created successfully : \"" + newlyCreatedRecordID  + "\""); });
}

· Update



function AsyncUpdateRecord() {
  var contact = new Sdk.Entity("contact");
  contact.addAttribute(new Sdk.Guid("contactid", "GUID ");  //Use the GUID value of user record
  contact.addAttribute(new Sdk.String("lastname", "Async record Last Name Updated"));
  Sdk.Async.update(contact, function () {
    alert("Contact updated successfully.");
  });
}

· Delete



function AsyncDeleteRecord() {
 //Use the GUID value of contact record
  Sdk.Async.del("contact", "GUID", function () {
    alert("Contact deleted successfully.");
  });
}

· Retrieve



function AsyncReteriveRecord() {
  var columnSet = new Sdk.ColumnSet();
  columnSet.addColumn("fullname");
 //Use the GUID value of contact record
  Sdk.Async.retrieve("contact", "GUID", columnSet, function (contact) {
    alert("Retrieved contact : \"" + contact.getValue("fullname") + "\"");
  });
}

· RetrieveMultiple



o QueryByAttribute



function AsyncRetrieveMultipleByQueryByAttribute () {
  var fetchQuery = new Sdk.Query.QueryByAttribute("contact");
  fetchQuery.setColumnSet("fullname");
  fetchQuery.addAttributeValue(new Sdk.String("middlename", "middle"));
  Sdk.Async.retrieveMultiple(fetchQuery, RetrieveMultipleCallBack);
}


o QueryExpression



function AsyncRetrieveMultipleByQueryExpression () {
  var fetchQuery = new Sdk.Query.QueryExpression("contact");
  fetchQuery.addColumn("fullname");
  var middleName = "middle";
  var values = new Sdk.Query.Strings([middleName]);
  fetchQuery.addCondition("contact", "middlename", Sdk.Query.ConditionOperator.Equal, values);
  Sdk.Async.retrieveMultiple(fetchQuery, RetrieveMultipleCallBack);
}

o FetchExpression




function AsyncRetrieveMultipleByFetchXML () {
  var fetchXml = ["<fetch version=\"1.0\" output-format=\"xml-platform\" mapping=\"logical\" distinct=\"false\">",
                    "<entity name=\"contact\"> ",
                    "  <attribute name=\"fullname\" /> ",
                    "  <order attribute=\"fullname\" descending=\"false\" /> ",
                    "  <filter type=\"and\"> ",
                    "    <condition attribute=\"middlename\" operator=\"eq\" value=\"middle\" /> ",
                    "  </filter> ",
                    " </entity> ",
                    " </fetch>"].join("");
  var fetchQuery = new Sdk.Query.FetchExpression(fetchXml);
  Sdk.Async.retrieveMultiple(fetchQuery, RetrieveMultipleCallBack);
}

· Associate

For this message, I’ve created custom many-to-many relationship between account and contact i.e. new_contact_account



function AsyncAssociateRecord() {
  //Use the GUID value of account record
  var account = new Sdk.EntityReference("account", "GUID");
  var collection = new Sdk.Collection(Sdk.EntityReference, new Array(account));
  //Use the GUID value of contact record
  Sdk.Async.associate("contact", "GUID", "new_contact_account", collection);
  alert("Contact - Account Associated");
}

· Disassociate

For this message, I’ve created custom many-to-many relationship between account and contact i.e. new_contact_account



function AsyncDisassociateRecord() {
  //Use the GUID value of account record
  var account = new Sdk.EntityReference("account", "GUID");
  var collection = new Sdk.Collection(Sdk.EntityReference, new Array(account));
  //Use the GUID value of contact record
  Sdk.Async.disassociate("contact", "GUID", "new_contact_account", collection);
  alert("Contact - Account Disassociated");
}

· SetState

This message is not included in common messages file i.e. Sdk.Soap.vsdoc.js. They provided a separate file, the Sdk.SetState.vsdoc.js to incorporate this message. To use this file we need to slightly change the existing code. We need to add the following line as the first line of the Sdk.SetState.vsdoc.js file,

Sdk = window.Sdk || { __namespace: true };

And we need to include two files at entity form load event:

Sdk.Soap.vsdoc.js

Sdk.SetState.vsdoc.js

Now, we are all set to use the following method.



function jQuerySetStateActivateRecord() {
//Use the GUID value of contact record
  var contactMoniker = new Sdk.EntityReference("contact", "GUID");
  var setStateRequest = new Sdk.SetStateRequest(contactMoniker, 0, 1); 
  //To deactivate record, use same code just pass state = 1 and status = 2) at above line
  Sdk.Async.execute(setStateRequest, function () { alert("Contcat Activated."); });
}

Note: If you do not want to change the Sdk.soap.vsdoc.js file by removing unrequired namespaces then I recommend to use the minified version of the same file i.e. Sdk.soap.min.js. This file is also bundled in this library.

For more details, please refer the following links:

http://code.msdn.microsoft.com/SdkSoapjs-9b51b99a

http://code.msdn.microsoft.com/SdkSoapjs-Samples-378151cd

I would be covering the sample code of other 3 namespaces in my upcoming posts.

I hope this would be helpful.

 




The simplest and quickest way to insert data for Many-to-Many relationship in Dynamics CRM is the Drag and drop listbox.

http://www.inkeysolutions.com/DynamicCRMDragAndDropListBox.html

5 comments:

  1. Great Work !!! achieved what I wanted Thanks a Lot

    Rarely developer use these methods soap methods . Only when we are in the the gray area.

    ReplyDelete
  2. Hi Ankit, can please give an example on how to use early binding in javascript.

    ReplyDelete
    Replies
    1. Hello Ramakanta,

      Sorry for the delayed response.

      I would recommend to review the following link to use early binding in JavaScript.

      https://code.msdn.microsoft.com/SdkSoapjs-Entity-Class-14ca830f

      Thanks,
      Ankit

      Delete
  3. hi i am new in crm and i download the sdksoapjs library but what is next step and how to use it and test it.please provide me step by step. thank you.

    ReplyDelete
  4. Hi Ankit,
    Thank you so much for this Article.Actually this article saved my life today.
    Thanks again.

    ReplyDelete