Use the REST Endpoint with Ajax and JScript Web Resources

[Applies to: Microsoft Dynamics CRM 2011]

The REST endpoint lets you interact with Microsoft Dynamics CRM 2011 data by using Microsoft JScript libraries. You create script web resources using files defining the JScript libraries. Then you associate functions in the libraries with form or field event handers or ribbon command actions. You can use them as you would any other JScript library within webpage (HTML) web resources.

In This Topic

Ajax

AJAX (Asynchronous JavaScript and XML) is a web development technique used to create interactive web applications. Server requests are made from the browser in the background using an XmlHttpRequest object. While you can send synchronous requests, the recommended practice is to send asynchronous requests. Asynchronous requests require two JScript functions, one to send the request and a second “callback” function to process a response.

JSON

JavaScript Object Notation (JSON) format is used for serializing and transmitting structured data much in the same way that XML is typically used. Like XML, it is text based and designed to be readable by humans. To convert regular JScript objects into the JSON format you use the JSON.stringify method. Because the text in JSON defines JScript objects, the text could be converted to JScript objects by using the eval method. However, this practice creates security vulnerabilities. You should use the JSON.parse method instead.

While Internet Explorer 8 does provide native support for JSON, this object is only available on a server or web page that has been configured to support Internet Explorer 8 compatibility. By default, Microsoft Dynamics CRM is configured to support Internet Explorer 7 or higher and does not specify compatibility with Internet Explorer 8.

To use JSON in Microsoft Dynamics CRM, you should create a JScript web resource that contains the minified contents of json2.js. This library is available for download here.

TipTip
You can use the Microsoft Ajax Minifier to reduce the size of your JScript libraries.

For more information, see http://www.json.org/

noteNote
There is a JSON viewer application available at http://jsonviewer.codeplex.com/ that includes a plug-in for Fiddler. This can be a useful tool for visualizing the JSON data returned by the REST endpoint.

XmlHttpRequest

XmlHttpRequest (sometimes referred to as XHR) provides capabilities to configure and send requests and define a callback function if the request is asynchronous. The HTTP response from the server includes a status code indicating whether the request was successful. HTTP status code values in the 200 range are considered successful.

An XmlHttpRequest provides instructions to the server about the format of any data to be included in the response. Because the REST endpoint supports both ATOM and JSON formats you have the option to request data to be returned in the XML ATOM format. However, with JScript code the expected typical request will use JSON because it is easily consumable using JScript.

Method Tunneling through POST

The OData protocol uses less common HTTP verbs PUT and DELETE as well as defining a new verb: MERGE. Depending on the supporting libraries you use, you may encounter issues while using these verbs. The way to work around this is to use the POST verb and specify a X-HTTP-Method HTTP header with the desired action. Use the setRequestHeader method to override the action specified in the XmlHttpRequest.

Accessing the URL to the server

The first thing to do when you start to use the REST endpoint with JScript is establish the URL to the organization root URL. Use the getServerUrl function from the context object.

Using jQuery

jQuery is a popular JavaScript library that is included with web application projects in Microsoft Visual Studio 2010. jQuery provides an extensive framework of objects and functions that let you query and work with HTML pages using JScript. To use HTTP requests, jQuery provides the jQuery.ajax method.

noteNote
The only supported use of jQuery in the Microsoft Dynamics CRM 2011 web application is to use the jQuery.ajax method to retrieve data from the REST endpoint. Using jQuery to modify Microsoft Dynamics CRM 2011 application pages or forms is not supported. You may use jQuery within your own HTML web resource pages.

The jQuery object is referenced using the $ character so the short form for jQuery.ajax is $.ajax. The ajax method is typically used with an imperative syntax and the request is sent as soon as the object is instantiated. The following sample creates a new account record.

    var account = {};
    account.Name = "Sample Account";
    var jsonAccount = window.JSON.stringify(account);
    $.ajax({ 
        type: "POST",
        contentType: "application/json; charset=utf-8",
        datatype: "json",
        url: Xrm.Page.context.getServerUrl() + "/XRMServices/2011/OrganizationData.svc/AccountSet",
        data: jsonAccount,
        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) {
            account = data.d;
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            errorHandler(XMLHttpRequest, textStatus, errorThrown);
        }
    });

The following table lists the properties you will have to know about to process HTTP requests and responses using the REST endpoint for Microsoft Dynamics CRM.

 

Property Name Type Comments

type

string

Use GET when you are retrieving data and POST for all other operations. For more information, see Explicitly set the Request header to a different HTTP action.

contentType

string

Specifies the type of content sent to the server. Use application/json; charset=utf-8 when you are sending data in JSON format.

dataType

string

The type of data expected to be returned by the server. Use json.

noteNote
Simply setting this property may be insufficient. For more information, see Explicitly set the Request Header to accept JSON.

data

object

Set this to the value of a JSON object for create or update operations.

url

string

The REST endpoint URL appropriate for the action you are performing.

beforeSend

function

A function that lets you modify the XMLHttpRequest object before it is sent.

success

function

A callback function when a request succeeds. For more information, see Processing results.

error

function

A function to be called if a request fails. For more information, see Handling errors.

For more information, see Sample: Create, Retrieve, Update and Delete Using the REST Endpoint with JavaScript and jQuery.

Explicitly set the Request Header to accept JSON

When you are expecting results back in JSON format just setting the dataType property might not work. You can use the beforeSend property to explicitly set the headers on the XMLHttpRequest to return data as JSON. This is typically performed by using an anonymous function as shown in the following example.

beforeSend: function (XMLHttpRequest) {
   //Specifying this header ensures that the results will be returned as JSON.
   XMLHttpRequest.setRequestHeader("Accept", "application/json");
}

When specified, any errors in XMLHttpRequest.responseText will be formatted in JSON instead of in XML.

TipTip
Even when you do not expect any data to be returned, specifying that the results are always returned using JSON will simplify your error handling. For more information, see Handling errors

Explicitly set the Request header to a different HTTP action

As described in Method Tunneling through POST, when you are performing an action that requires an HTTP action other than POST or GET, use POST and the beforeSend property to explicitly set the headers on the XMLHttpRequest to perform a different action. This is typically performed by using an anonymous function, as shown in the following example.

beforeSend: function (XMLHttpRequest) {
   //Specify the HTTP method DELETE to perform a delete operation.
   XMLHttpRequest.setRequestHeader("X-HTTP-Method", "DELETE");
}

Handling errors

When a request is not successful $.ajax will pass the following three arguments to a function set in the error property.

XMLHttpRequest
The XMLHttpRequest object.

textStatus
A string that describes the type of error that occurred. The possible values are as follows:

  • null

  • timeout

  • error

  • notmodified

  • parsererror

errorThrown
An optional exception object.

The following sample shows how to pass these arguments to a central function that manages errors:

error: function (XMLHttpRequest, textStatus, errorThrown) {
   errorHandler(XMLHttpRequest, textStatus, errorThrown);
}

The following sample shows a simple function that captures the error message and displays the result using showMessage function.

noteNote
This function expects that any error details will be returned in JSON format. Unless the $.ajax method is configured to return results using JSON, the XMLHttpRequest.responseText would be XML.


function errorHandler(XMLHttpRequest, textStatus, errorThrown)
{ showMessage("Error : " + textStatus + ": " + JSON.parse(XMLHttpRequest.responseText).error.message.value); }

Processing results

When you perform POST or GET operations you can expect that data will be returned. If you have specified that result be returned in JSON format, the results will be in the d property of the data object returned. When you are creating a record or retrieving a single record using the unique identifier, d will represent the data for the record. In every other case d will be an array.

The following sample shows processing the results of a query that returns multiple account records.

success: function (data, textStatus, XmlHttpRequest) {
   var accounts = data.d;
   for (var i in accounts) {
   showMessage(accounts[i].Name);
   }
}

Using XMLHttpRequest

jQuery is a great library with a variety of uses, but using jQuery is not a prerequisite for performing operations using the REST endpoint for Microsoft Dynamics CRM. jQuery$.ajax actually uses the XmlHttpRequest available in Internet Explorer. Using this object directly is just slightly different from using $.ajax. If you are already familiar with using XMLHttpRequest you can continue to use it. For more information, see XMLHttpRequest Object.

With XmlHttpRequest you must create an event handler for the onreadystatechange event and detect when the request has completed. In the event handler you must check the status code returned to determine whether the request succeeded. Finally, you must use the open and send methods. The following sample uses XmlHttpRequest to create a new account record.


    var account = {};
    account.Name = "Sample Account";
    var jsonAccount = JSON.stringify(account);

    var createAccountReq = new XMLHttpRequest();
    createAccountReq.open("POST", Xrm.Page.context.getServerUrl() + "/XRMServices/2011/OrganizationData.svc/AccountSet", true);
    createAccountReq.setRequestHeader("Accept", "application/json");
    createAccountReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    createAccountReq.onreadystatechange = function () {
        createAccountReqCallBack(this);
    };
    createAccountReq.send(jsonAccount);

function createAccountReqCallBack(createAccountReq) {
    if (createAccountReq.readyState == 4 /* complete */) {
        createAccountReq.onreadystatechange = null; //avoids memory leaks
        if (createAccountReq.status == 201) {
            //Success
            var newAccount = JSON.parse(createAccountReq.responseText).d;
        }
        else {
            //Failure
            errorHandler(createAccountReq);
        }
    }
};

For more examples using XMLHttpRequest, see Sample: Create, Retrieve, Update and Delete Using the REST Endpoint with JavaScript

Working with Dates

There are four tasks involving dates that you may need to perform:

Parsing Retrieved Data

When you retrieve records using the REST endpoint date values are returned as strings that use the format “\/Date(<ticks>)\/” where <ticks> is the number of milliseconds since midnight January 1, 1970. For example: "\/Date(1311170400000)\/". All values returned from Microsoft Dynamics CRM represent the Universal Coordinated time (UTC) values so no offset information is included.

There are two strategies you can use to parse dates in records returned using the REST endpoint:

Use a Reviver Function with the JSON.parse Method

The JSON.parse method supports an optional reviver argument as described in the JSON.parse method documentation on MSDN. The following is an example that will convert the string values that match a pattern defined in a regular expression into Date objects:

var jsontext = '{ "hiredate": "\/Date(1311170400000)\/", "birthdate": "\/Date(-158342400000)\/" }';
var dates = JSON.parse(jsontext, dateReviver);
var string = dates.hiredate.toUTCString();
// The value of string is "Wed, 20 Jul 2011 14:00:00 UTC"

function dateReviver(key, value) {
 var a;
 if (typeof value === 'string') {
  a = /Date\(([-+]?\d+)\)/.exec(value);
  if (a) {
   return new Date(parseInt(value.replace("/Date(", "").replace(")/", ""), 10));
  }
 }
 return value;
};
noteNote
This code assumes that date values will always be UTC data values and will not include any offset information.

Use String.replace to Generate a Date Value From a String

If you do not use the reviver argument with the JSON.parse method the following example shows how you can generate a Date value from a string:

var dateValue = new Date(parseInt(stringDateValue.replace("/Date(", "").replace(")/", ""), 10));

Displaying Date Values

After the string date values are converted to Date objects, you can use a variety of JScript methods to display the date as a string that can be displayed in a user interface or you can create your own. Because the JScript Date object is UTC aware, the dates displayed in your user interface using methods such as toString or toLocaleString will reflect the time zone settings of the user’s operating system.

However, notice that the values in your application might be different from the same values displayed in Microsoft Dynamics CRM. Microsoft Dynamics CRM does not rely on the user’s operating system time zone settings. These values will be different when the user’s current operating system time zone preference does not match the time zone preference saved in Microsoft Dynamics CRM. Microsoft Dynamics CRM also allows for setting personalized presentation options that will not be applied by using standard JScript date functions like toString;

If you want to reconcile the displayed date and time values to match the values shown in Microsoft Dynamics CRM you can query data stored in the UserSettings entity and entities like TimeZoneDefinition and TimeZoneRule to create functions to display dates that match the user’s preference. Microsoft Dynamics CRM does not provide functions to perform these actions.

Updating Date Values

When you change the values of a JScript Date using the standard set methods, such as setMinutes or setHours it is understood that these changes are in the user’s local time. When you save the record the actual UTC values are serialized and saved back to Microsoft Dynamics CRM, you do not have to do anything to convert the dates to a UTC value.

When a Date is serialized the format differs from the format that was used when the data is retrieved. As noted in Parsing Retrieved Data, dates are retrieved as strings that use the format "\/Date(1311179400000)\/". When you examine the results of JSON.stringify for date values to be passed back to the server the format is "2011-07-20T16:30:00Z".

Setting a Date as Criteria in a Filter in a Query

When you use a date value with a $filter system query option, you must use a UTC date. To convert a JScript Date object into the format expected for a filter you have to process the date using a function such as the following example. The result is a string that matches the following format: datetime'2010-09-28T18:21:46:594Z' .

function getODataUTCDateFilter(date) {

 var monthString;
 var rawMonth = (date.getUTCMonth()+1).toString();
 if (rawMonth.length == 1) {
  monthString = "0" + rawMonth;
 }
 else
 { monthString = rawMonth; }

 var dateString;
 var rawDate = date.getUTCDate().toString();
 if (rawDate.length == 1) {
  dateString = "0" + rawDate;
 }
 else
 { dateString = rawDate; }


 var DateFilter = "datetime\'";
 DateFilter += date.getUTCFullYear() + "-";
 DateFilter += monthString + "-";
 DateFilter += dateString;
 DateFilter += "T" + date.getUTCHours() + ":";
 DateFilter += date.getUTCMinutes() + ":";
 DateFilter += date.getUTCSeconds() + ":";
 DateFilter += date.getUTCMilliseconds();
 DateFilter += "Z\'";
 return DateFilter;
}


See Also

Microsoft Dynamics CRM 2011
Send comments about this topic to Microsoft.
© 2013 Microsoft Corporation. All rights reserved.

Community Additions

ADD
Show: