Export (0) Print
Expand All

Use the OData endpoint with Ajax and JScript web resources

Applies To: Microsoft Dynamics CRM 2013, Microsoft Dynamics CRM Online

The OData endpoint lets you interact with Microsoft Dynamics CRM 2013 and Microsoft Dynamics CRM Online data by using JavaScript libraries. You create script web resources using files defining the JavaScript 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 JavaScript library within webpage (HTML) web resources.

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.

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 JavaScript objects into the JSON format you use the JSON.stringify method. Because the text in JSON defines JavaScript objects, the text could be converted to JavaScript objects by using the eval method. However, this practice creates security vulnerabilities. You should use the JSON.parse method instead.

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 ODATA endpoint supports both ATOM and JSON formats you have the option to request data to be returned in the XML ATOM format. However, with JavaScript code the expected typical request will use JSON because it is easily consumable using JavaScript.

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 ODATA endpoint with JavaScript is establish the URL to the organization root URL. Use the getClientUrl function from the context object.

Using XMLHttpRequest

jQuery is a great library with a variety of uses, but using jQuery is not a prerequisite for performing operations using the ODATA endpoint for Microsoft Dynamics CRM. We recommend you do not use jQuery in form scripts or command scripts that run in application pages but use the XmlHttpRequest directly and avoid having to load the jQuery library. jQuery$.ajax uses the XmlHttpRequest available in the browser. Using this object directly is just slightly different from using $.ajax. If you are already familiar with using XMLHttpRequest you should continue to use it. If you have always used jQuery, consider using XMLHttpRequest directly. 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.getClientUrl() + "/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 OData endpoint with JavaScript

Using jQuery

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

noteNote
We do not recommend using jQuery with form scripts or commands. More information: Use of jQuery.

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.getClientUrl() + "/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 ODATA 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 ODATA 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 OData 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 POST Tunneling, 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);
   }}

Working with Dates

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

Parsing Retrieved Data

When you retrieve records using the ODATA 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 ODATA 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 JavaScript methods to display the date as a string that can be displayed in a user interface or you can create your own. Because the JavaScript 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 JavaScript 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 JavaScript 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 "2013-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 JavaScript 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 2013 and Microsoft Dynamics CRM Online
Send comments about this topic to Microsoft.
© 2014 Microsoft Corporation. All rights reserved.
Show:
© 2014 Microsoft