Use the OData endpoint with Ajax and JScript web resources
Applies To: Dynamics CRM 2013
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 handlers or ribbon command actions. You can use them as you would any other JavaScript library within webpage (HTML) web resources.
In This Topic
Ajax
Method tunneling through POST
Access the server URL
Use XMLHttpRequest
Use jQuery
Work with dates
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. Although 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
The 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
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’s 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 an X-HTTP-Method HTTP header with the desired action. Use the setRequestHeader method to override the action specified in the XmlHttpRequest.
Access the server URL
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.
If your script is designed to operate in the context of a form or field event, or a <JavaScriptFunction> (RibbonDiffXml) for a ribbon command, you can use the Xrm.Page.context object to call getClientUrl.
If your script executes in the context of a webpage (HTML) web resource you must include a reference to the ClientGlobalContext.js.aspx page in the HTML web resource so that you can then use the GetGlobalContext function.
Use 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 don’t 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 slightly different from using $.ajax. If you’re already familiar with using XMLHttpRequest you should continue to use it. If you have always used jQuery, consider using XMLHttpRequest directly. More information: XMLHttpRequest Object
With XmlHttpRequest, you create an event handler for the onreadystatechange event and detect when the request has completed. In the event handler, check the status code returned to determine whether the request succeeded. Finally, 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
Use 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.
Note
We don’t 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’ll 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 retrieve data and POST for all other operations. More information: 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’re sending data in the JSON format. |
dataType |
string |
The type of data expected to be returned by the server. Use json. Note Simply setting this property may be insufficient. More information: 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’re performing. |
beforeSend |
function |
A function that lets you modify the XMLHttpRequest object before it’s sent. |
success |
function |
A callback function when a request succeeds. More information: Process results |
error |
function |
A function to be called if a request fails. More information: Handle 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’re expecting results in a 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.
Tip
Even when you don’t expect any data to be returned, specifying that the results are always returned using JSON will simplify your error handling. More information: Handle errors
Explicitly set the request header to a different HTTP action
As described in Method tunneling through POST, when you perform 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");
}
Handle errors
When a request isn’t 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 the showMessage function.
Note
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); }
Process results
When you perform POST or GET operations you can expect that data will be returned. If you have specified that results be returned in the JSON format, the results will be in the d property of the data object returned. When you create or retrieve a 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);
}}
Work with dates
There are four tasks involving dates that you may need to perform:
Parse retrieved data
Display date values
Update date values
Set a date as criteria in a filter in a query
Parse 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 Coordinated Universal 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
Use String.replace to generate a date value from a string
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 converts 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;
};
Note
This code assumes that date values will always be UTC data values and won’t include any offset information.
Use String.replace to generate a date value from a string
If you don’t 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));
Display date values
After the string date values are converted to Date objects, you can use a variety of JavaScript methods, or create your own, to display the date as a string in a user interface. 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, which doesn’t 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 doesn’t match the time zone preference saved in Microsoft Dynamics CRM. Microsoft Dynamics CRM also allows for setting personalized presentation options that won’t 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 doesn’t provide functions to perform these actions.
Update date values
When you change the values of a JavaScript date using standard set methods such as setMinutes or setHours, 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 don’t 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 Parse 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".
Set 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
Use the OData endpoint with web resources
OData endpoint Http status codes
JavaScript libraries for Microsoft Dynamics CRM 2013
Script (JScript) web resources
Associate functions with Form and Field events
jQuery.ajax method
XMLHttpRequest Object
Technical Article: Using Option Set Options with the ODATA Endpoint - JScript