Creating records from Jscript in Microsoft CRM using REST

With CRM 2011 and the REST End Point we now have an easy to use syntax for executing creating, updating and retrieving CRM records from jscript.  In this blog I’m going to demonstrate the approach for creating records.

I want to demonstrate a very simple scenario to give you a gentle introduction to REST, so let’s just create a new Account record with the name "TEST".  We will need our code to be triggered in some manner so lets just register it to run on the OnLoad event of the Letter form (an entity you probably haven’t customised in your development environment yet).  If you can get this working you will be able to add similar code to a custom Ribbon button or to a more applicable form event.

First thing you need to do is load into your CRM a couple of generic jscript libraries which contain ‘stuff we need’.  So, download the latest json2 and jquery libraries and load them into your CRM as jscript web resources.  Here’s the links:

http://www.json.org/json2.js.

http://jquery.com/

I downloaded these 2:

image

And loaded them into my CRM:

image

Whist you are there create a 3rd jscript web resource and paste this code into it:

// JScript source code 
function LetterOnLoad() { 
    var context = Xrm.Page.context; 
    var serverUrl = context.getServerUrl(); 
    var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc"; 
    var CRMObject = new Object(); 
    ///////////////////////////////////////////////////////////// 
    // Specify the ODATA entity collection 
    var ODATA_EntityCollection = "/AccountSet"; 
    ///////////////////////////////////////////////////////////// 
    // Define attribute values for the CRM object you want created 
    CRMObject.Name = "TEST"; 
    CRMObject.Telephone1 = "123"; 
    CRMObject.Fax = "456"; 
    //Parse the entity object into JSON 
    var jsonEntity = window.JSON.stringify(CRMObject); 
    //Asynchronous AJAX function to Create a CRM record using OData 
    $.ajax({ type: "POST", 
        contentType: "application/json; charset=utf-8", 
        datatype: "json", 
        url: serverUrl + ODATA_ENDPOINT + ODATA_EntityCollection, 
        data: jsonEntity, 
        beforeSend: function (XMLHttpRequest) { 
            //Specifying this header ensures that the results will be returned as JSON. 
            XMLHttpRequest.setRequestHeader("Accept", "application/json"); 
        }, 
        success: function (data, textStatus, XmlHttpRequest) { 
            alert("success"); 
            var NewCRMRecordCreated = data["d"]; 
            alert("CRM GUID created: " + NewCRMRecordCreated.AccountId); 
        }, 
        error: function (XMLHttpRequest, textStatus, errorThrown) { 
            alert("failure"); 
        } 
    }); 
}

Ok, now we need to go and add this to the Letter entity.  So get into the onload event of the Letter’s main form and add these 3 jscript libraries:

image

I think the ordering is important so make sure the 3rd library you created to hold the code above is listed last.  It refers to functions that the other 2 libraries provide.

In the lower half of that Form Properties window we need to specify the function we want to execute at the form load event.   Add the LetterOnLoad function there:

image

Ok, that should work.  You didn’t need to localise anything, the necessary references are derived.  Simply, save, publish all, and then pop the Letter form.

The end result should be:

A success alert…

image

… followed by a second message providing the GUID of the Account record created…

image

… and the proof that something actually happened, a shiny new Account record in your CRM system:

image

So that should be enough to get you started.  The code snippet I have provided is not tied to the Letter entity or to the onload event so you should be able to relocate it to another event or put it behind a ribbon button.   If you want it to run outside of CRM you need to handle the context using GetGlobalContext.

Here’s some more comments on what the code is doing to help you understand how to change it to match your requirements…

First do a bunch of connectivity stuff and define a new variable for our Account record called “CRMObject”.  You don’t need to touch this:

var context = Xrm.Page.context; 
var serverUrl = context.getServerUrl(); 
var ODATA_ENDPOINT = "/XRMServices/2011/OrganizationData.svc"; 
var CRMObject = new Object();

Next we name the CRM entity that we want to create.   Enter your entity name as I have done for Account – i.e. prepend a “/” and append “Set” – e.g. for Contact you will enter “/ContactSet”:

///////////////////////////////////////////////////////////// 
// Specify the ODATA entity collection 
var ODATA_EntityCollection = "/AccountSet";

Now we need to define the field values of our record that we want created.  We already declared our CRMObject variable, now we give it attribute values:

///////////////////////////////////////////////////////////// 
// Define attribute values for the CRM object you want created 
CRMObject.Name = "TEST"; 
CRMObject.Telephone1 = "123"; 
CRMObject.Fax = "456";

So my example was pretty simple I was just provided hardcoded values but of course you could have a bunch of logic here to come up with the values you want.

I hit some snags here as things are case sensitive and I wasn’t sure what the right case was.  To figure that out I suggest you browse the REST End Point using the relevant URL.  Here’s my URL for the Account entity for my online instance.  If you’re running CRM 2011 online just swap out the org name in yellow and specify whatever entity you are interested in where I have Account in green:

https://avanade10.crm5.dynamics.com/XRMServices/2011/OrganizationData.svc/AccountSet

Simply navigating to this URL has the effect of submitting the following query:  “Select the first 50 records from the Account entity”. 

You’ll either see the data returned in a sort of feed format or as raw XML.   I saw the data in feed format (which is pretty, but not too useful)…

image_thumb3

… until I followed these instructions:

To view the data in Internet Explorer , you must first make sure that Internet Explorer is not enabled to format RSS feed. In the Content tab of Internet Options. select Settings in the Feeds and Web Slices group. Then, click to clear the Turn on feed reading view option. Close and re-open Internet Explorer .

Now I see it like this:

image_thumb1

Each <entry> node is an individual Account record.  Under each Account you will see first all the link references to each related entity and then below that under the <m:properties> node you will see each property of the Account record:

image_thumb5

Here you can check the case of the field name.

Moving on, the rest of the code executes the creation request and deals with the asynchronous response.  In the success function I create an object variable “NewCRMRecordCreated ” to hold the record created by the request.  I can then extract field values of that object and do more stuff. 

In my example I am dealing with an Account record and want to display the Account ID so you will see that mentioned and you will need to change that if you change my example to work with a different CRM entity:

success: function (data, textStatus, XmlHttpRequest) { 
    alert("success"); 
    var NewCRMRecordCreated = data["d"]; 
    alert("CRM GUID created: " + NewCRMRecordCreated.AccountId); 
},

I hope this of help to someone out there.   Smile

About these ads

18 thoughts on “Creating records from Jscript in Microsoft CRM using REST

  1. Hi Gareth,

    I tried using this but I got the jQuery Ajax ‘No Transport’ error.
    Our CRM 2011 is installed on server (on-premise).

    Do you have any idea how to fix this?

    Thanks,
    Andreas

  2. Thank you. I completely missed that setting in IE. I just finished up a Silverlight app which took me three times longer than it should have. This will help a lot in the future. Especially now that I can use the Codeplex OData Query Designer. It only works for on-premise implementations unless you click the “Show in Browser” button, which before showed me the same fairly useless window shown in your original post.

  3. Pingback: Defaulting a Lookup field via a REST query at Form Load « Gareth Tucker's Microsoft CRM Blog
  4. This works great! Much appreciated. Can you please point me in the direction of passing a lookup value to the new record?

  5. Pingback: Filtered Lookup Approaches in CRM 2011 « Gareth Tucker's Microsoft CRM Blog
  6. It a Greate post, but i need to notify that the following link to download json2 you gave is wrong. I have used the json2 from the SDK..And it worked perfectly.

  7. Pingback: Supporting Environment-specific Parameters in CRM 2011 Jscript « Gareth Tucker's Microsoft CRM Blog
  8. Hi , thanks for your greate post. I try to do this and it works for Account , but for Contact I get failure message. Can you tell me what’s the problem?

  9. Hi Gareth, thanks for the blog, I have used it in my solution. Wonder if you could advise how I would create a record with an association lookup field? your example updates text fields, I need to pass the GUID of the current record to a lookup field in the new record. This should create the association.

  10. Hi there, just became aware of your weblog through Google, and located that it is truly informative. I am going to be careful for brussels. I’ll appreciate when you proceed this in future. A lot of other people will probably be benefited out of your writing. Cheers!

  11. I know you said I can just replace “AccountSet” with “OpportunitySet” but for some reason, AccountSet works but OpportunitySet does not. Any idea? Thank you so much for any help. Here is my code by the way.

    var newOpportunity = new Object();

    newOpportunity.Name = “TEST”;
    newOpportunity.StatusCode = 0;

    var contact = new Object();
    contact.Id = “b4531ee9-9477-4262-8e18-00b60369352a”;
    contact.LogicalName = “contact”;
    contact.Name = “Bacon Jones”;

    newOpportunity.ContactId = contact;

    var jsonNewOpp = window.JSON.stringify(newOpportunity);

    $.ajax({ type: “POST”,
    contentType: “application/json; charset=utf-8″,
    datatype: “json”,
    url: Xrm.Page.context.getServerUrl() + “/XRMServices/2011/OrganizationData.svc/OpportunitySet”,
    data: jsonNewOpp,
    beforeSend: function (XMLHttpRequest) {
    XMLHttpRequest.setRequestHeader(“Accept”, “application/json”);
    },
    success: function (data, textStatus, XmlHttpRequest) {
    alert(“success”);
    //var getNewRecord = data["d"];
    //alert(“GUID: ” + getNewRecord.OpportunityId);
    },
    error: function (XMLHttpRequest, textStatus, errorThrown) {
    alert(“failure due to ” + errorThrown);
    }
    });

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s