XrmServiceToolkit is a JavaScript library which could be used to make

  • Common Methods: Change of CRM form like enable field, show field, etc
  • Rest EndPoint Methods: Create, Retrieve, Update a record, etc
  • Soap Request Methods: Create, Retrieve, Update a record, etc
  • Extension Methods: Setup Dependent OptionSet, Add Tooltip to fields, Add custom filter view to lookup field. All these methods are generic to use and configurable through editing of XML web resource.

CRM 2013 Upgrade and Preparation

Debug / Unit Test JavaScript Rest or Soap in Visual Studio For CRM 2011

Project Highlight and Notes: Current Release - Version 2.0.1 (April, 2014)

* @current version : 2.0.1

* Date: April, 2014

* Dependency: JSON2, jQuery (latest or 1.7.2 above)

* Feature: Add Cross Browser Support for CRM 2011 with RU16, CRM 2013 with RU2

* Tested Platform: IE9, IE10, IE11, Chrome Version (latest), Firefox (latest)

If you have used the toolkit previously for your project, thanks very much for your support. For version 1.4.1, download and try it out using a testing environment and let me know issues and bugs.

Happy Coding,
Jaimie 

For examples with qunit, please follow the links

Cross Browser Support

Cross Browser support and Cross platform are aligned with Dynamics CRM Roadmap with Microsoft Release

Qunit Refresh and Test Results

Qunit plays a big part during the development and continous development for this project. [NOTE] Qunit is for unit testing. You do not need the part of the code in live code

Qunit test result

Code Examples in the documentation.

All code examples or most of them are using in combination with Qunit. The qunit part of the code is not required in real life situation.

Synchronous and Asynchronous

The basics of synchronous and asynchronous calls are still the same without jQuery. As the reason not too sure yet , jQuery 1.8 will not support ajax asynch=false anymore. However in reality, there will be still usage, for example onSave, synchronous calls might still required. For best practise, asynchronous calls should be used for better performance.

XrmServiceToolkit.Rest funcitons use the last boolean parameter to indicate if the method runs asychronously or synchronously. If false is assigned, then the method will run synchronously, otherwise an asynchrounous method will be called.

 

var contact = {};
contact.FirstName = "Diane";
contact.LastName = "Morgan";
contact.MiddleName = "<&>";
contact.GenderCode = { Value: 2 };
contact.CreditLimit = { Value: "2.00" };
contact.BirthDate = birthDate;
contact.DoNotEMail = true;
contact.DoNotPhone = true;

XrmServiceToolkit.Rest.Create(
	contact,
	"ContactSet",
	function (result) {
		contactId = result.ContactId;
	},
	function (error) {
		alert(error.message);
	},
	false //synchronous call
);
 
var contact = {};
contact.FirstName = "Diane";
contact.LastName = "Morgan";
contact.MiddleName = "<&>";
contact.GenderCode = { Value: 2 };
contact.CreditLimit = { Value: "2.00" };
contact.BirthDate = birthDate;
contact.DoNotEMail = true;
contact.DoNotPhone = true;

XrmServiceToolkit.Rest.Create(
	contact,
	"ContactSet",
	function (result) {
		contactId = result.ContactId;
	},
	function (error) {
		alert(error.message);
	},
	true //asynchronous call
);

 

XrmServiceTookit.Soap functions using the last function parameter to indicate if the method runs asychronously or synchronously. If the funciton is defined, the method will run asychronously. Otherwise, the method will be called synchronously.

var cols = ["firstname", "lastname", "middlename", "familystatuscode", "ownerid", "creditlimit", "birthdate", "donotemail", "donotphone"];
var retrievedContact = XrmServiceToolkit.Soap.Retrieve("contact", contactId, cols); //synchronous call
var familyStatusLable = retrievedContact.attributes['familystatuscode'].formattedValue;
var firstName = retrievedContact.attributes['firstname'].value;
var cols = ["firstname", "lastname", "middlename", "familystatuscode", "ownerid", "creditlimit", "birthdate", "donotemail", "donotphone"];
XrmServiceToolkit.Soap.Retrieve("contact", contactId, cols, function(result){
    var familyStatusLable = result.attributes['familystatuscode'].formattedValue;	
    var firstName = result.attributes['firstname'].value;
}); //asychronous call

Numbers

CRM 2011 has number like whole number (int), floating point (double) and Decimal number (decimal), Currency (Money).

When using the soap funcitons in the library, it is recommended to include type when assigning values. It is more likely to cause issue for fields like decimal or double

//overcome limitations of numbers with type specified.... 
createContact.attributes["numberofchildren"] = { value: 2, type: "int"}; 

createContact.attributes["exchangerate"] = {value: 1.5617, type: "decimal"}; 

createContact.attributes["address1_latitude"] = { value: 1.5617, type: "double" }; 

createContact.attributes["creditlimit"] = { value: 2, type: "Money" }; 

FormattedValue

The XrmServiceToolkit.Soap functions have an extra attribute returned as formattedValue. It could be very useful if you want to return some extra information. For example, to get the lable of OptionSet. The example is synchrous.

var cols = ["firstname", "lastname", "middlename", "familystatuscode", "ownerid", "creditlimit", "birthdate", "donotemail", "donotphone"];
var retrievedContact = XrmServiceToolkit.Soap.Retrieve("contact", contactId, cols);
var familyStatusLable = retrievedContact.attributes['familystatuscode'].formattedValue;//label
var familyStatusValue = retrievedContact.attributes['familystatuscode'].value; //integer

An example to create email activity using the library.

    var createEmail = new XrmServiceToolkit.Soap.BusinessEntity("email");
    createEmail.attributes["subject"] = "Test Email subject";
    createEmail.attributes["description"] = "This email was created by the XrmServiceToolkit.Soap.Create() sample.";

    var from = [
       { id: whoamiUserId, logicalName: "systemuser", type: "EntityReference" }
    ];

    createEmail.attributes["from"] = { value: from, type: "EntityCollection" };

    var to = [
       { id: accountId, logicalName: "account", type: "EntityReference" },
       { id: contactId, logicalName: "contact", type: "EntityReference" }
    ];

    createEmail.attributes["to"] = { value: to, type: "EntityCollection" };

    var cc = [
       { id: accountId, logicalName: "account", type: "EntityReference" },
       { id: contactId, logicalName: "contact", type: "EntityReference" }
    ];

    createEmail.attributes["cc"] = { value: cc, type: "EntityCollection" };

    var bcc = [
       { id: accountId, logicalName: "account", type: "EntityReference" },
       { id: contactId, logicalName: "contact", type: "EntityReference" }
    ];

    createEmail.attributes["bcc"] = { value: bcc, type: "EntityCollection" };

    createEmail.attributes["directioncode"] = true;

    emailId = XrmServiceToolkit.Soap.Create(createEmail);

An example to retrieve an email is like this. The returned value of [From/To/Cc/Bcc] is an array of Entity reference.

    var cols = ["subject", "description", "from", "to", "cc", "bcc", "directioncode"];
    var retrievedEmail = XrmServiceToolkit.Soap.Retrieve("email", emailId, cols);

var subject = retrievedEmail.attributes['subject'].value; var description = retrievedEmail.attributes['description'].value;

To get the value of an array item of the returned result. Using something like

var sender = retrievedEmail.attributes['from'].value[0];

Then you can get sender.id, sender.type, sender.logicalName, sender.Name per normal as a returned EntityReference value.

An example to use the GrantAccess is like this. For all other examples, please have a look at the attached aspx page.

     var accessOptions = {
         targetEntityName: "contact",
         targetEntityId: contactId,
         principalEntityName: "systemuser",
         principalEntityId: currentUserId,
         accessRights: ["ReadAccess", "WriteAccess"]
     };

     var grantAccessResponse = XrmServiceToolkit.Soap.GrantAccess(accessOptions);

[NOTE] These functions regarding access should be combined with CRM 2011 security model and they could be useful if entities have to be controlled at record level. This obviously has to be used with consideration of user rights, security settings and all other security related configurations as the requirement of the project.

For details about how to use all these methods and updated examples. See attached .aspx page for examples.

Credi: The code example is based on Daniel Cai's CrmWebServiceKit.

XrmServiceToolkitTest.zip

Dependency

JSON2 javascript library is required in CRM 2011 as a web resource to make the library working.

jQuery 1.7.2 above is required from version 1.3

To Unit Test your code at local machine.

There is a way to test all your Rest / Soap calls directy from your development machine without modifying the library which is achieved by using the XrmPageTemplate.js and PageData.js. For details about how to using JavaScript Intellisense, please have a look at this wonderful blog

http://crmbusiness.wordpress.com/2011/12/01/crm-2011-using-javascript-intellisense-and-testpage-htm/

Once you have got the PageData.js generated from any entity, simply put it in the helper folder to replace the existing PageData.js in the source code project which you could download from the [Source Code] section here.

Now you could run and debug the XrmServiceToolkitTest.aspx from your visual studio.

Happy Coding,

Jaimie

Last edited Apr 21, 2014 at 5:50 PM by jaimieji, version 88

Comments

JoeriB Nov 15, 2013 at 12:41 PM 
how to get the Id value from a lookup in a related entity ?
var cols = ["name","new_vatnumber","new_countryid"];
var retrievedAccount = XrmServiceToolkit.Soap.Retrieve("account", customerID, cols); //synchronous call
var accountname = retrievedAccount.attributes['name'].value;
var vatnumber = xrmfieldtest(retrievedAccount, "new_vatnumber");
(how do i get the countryid value ?)

jaimieji Nov 25, 2012 at 10:00 PM 
Hi Daniel Cai.

Credit added in the latest file.

Jaimie

danielcai Nov 17, 2012 at 7:23 AM 
Jamie, please make sure to add credit note to unit test page, since it is very much a copy of my unit test code. I don't want to give the community an impression that I am stealing your code.

Thanks,
Daniel Cai

hyperlinx Jul 19, 2012 at 1:48 PM 
in the example "create email" how you fill whoamiUserId, accountId, contactId?

jaimieji Jul 11, 2012 at 3:41 PM 
Hey jhzzheng.

The unit testing is just to test how the soap / rest logic works. For example, if you want to get addtional inforamtion from 'parent company' after selection in a contact form using the 'parent company' lookup. To unit test this, just get an ID of a company/account from CRM, then create a method to test your logic.

using the mocking page data, you could run your server (soap/rest) in your visual studio test page. The example below is an asychronous call.

var companyId = '';//the guid id of a company from your crm 2011 instance

var cols = ['new_country', 'telephone1', 'emailaddress1'];
XrmServiceToolkit.Soap.Retrieve('account', companyId, cols, function (result) {
var returnedEntity = result;
if (returnedEntity != null) {
var companyCountry = returnedEntity.attributes['new_country'].value;
var companyTelephone = returnedEntity.attributes['telephone1'].value;
var companyEmail = returnedEntity.attributes['emailaddress1'].value;

//Add logics here.
}
});

jhzheng Jun 29, 2012 at 4:23 AM 
I understood XrmPageTemplate.js and PageData.js are for mocking the CRM form. I just don't see how you can unit testing your REST or SOAP web calls to a server using mocking technology.

Can you provide more examples or instruction how to unit testing the REST or SOAP calls without an actual CRM server? Is it even possible? How can you mock the server behavior to respond to REST or SOAP call?


Much appreciated

jaimieji Jun 26, 2012 at 11:23 AM 
Link fixed. Thanks for pointing it out

salvattore001 Jun 7, 2012 at 11:56 PM 
XrmServiceToolkitTest.zip link is broken.. could you fix it please?
thanks

crminnovation Jun 5, 2012 at 10:46 PM 
Thanks for your reply.

jaimieji May 28, 2012 at 11:59 AM 
Hey There.

regardingobjectid is a EntityReference field. To create the email with regarding object, use

createEmail.attributes["regardingobjectid"] = { id: entityId, logicalName: entityName, type: "EntityReference" };

crminnovation May 24, 2012 at 10:39 PM 
Hi Jaimie,

I've used your above example with the email create, but I can't get your code to set the regardingobjectid property of the created email. Here's what I'm doing:


var regarding = [
{ id: Xrm.Page.data.entity.getId(), logicalName: logicalName, type: "EntityReference" }
];

createEmail.attributes["regardingobjectid"] = { value: regarding, type: "EntityCollection" };

The entity for the lookup is custom. The other fields populate correctly. Any suggestions?