// =====================================================================
// This file is part of the Microsoft Dynamics CRM SDK code samples.
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// This source code is intended only as a supplement to Microsoft
// Development Tools and/or on-line documentation. See these other
// materials for detailed information regarding Microsoft code samples.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// =====================================================================
if (typeof (SDK) == "undefined")
{ SDK = { __namespace: true }; }
SDK.REST = {
_Context: function () {
///<summary>
/// Private function that retrieves the context from either the Xrm.Page.context
/// or the GetGlobalContext function in ClientGlobalContext.js.aspx
///</summary>
var errorMessage = "Context is not available.";
if (typeof GetGlobalContext != "undefined") {
return GetGlobalContext();
}
else if (typeof Xrm != "undefined") {
return Xrm.Page.context;
}
else if (typeof parent.Xrm.Page.context != "undefined") {
return parent.Xrm.Page.context;
}
else {
return new Error(errorMessage);
}
},
_ODataUrl: function () {
///<summary>
/// Private function composes the OData URL using the _Context object.
///</summary>
//Detect if the hostname is an IP address then we return the IP address as the server destination instead of the server name (which will be unfound)
var urlReg = new RegExp(/http[s]?:\/\/[0-9.:]+\/[a-zA-Z0-9.-_~]+/i);
var ServerUrl = this._Context().getServerUrl();
if (window.location.href.match(urlReg) != null) {
ServerUrl = window.location.href.match(urlReg).toString();
}
if (ServerUrl.match(/\/$/)) {
ServerUrl = ServerUrl.substring(0, ServerUrl.length - 1);
}
return ServerUrl + "/XRMServices/2011/OrganizationData.svc";
},
retrieveMultipleSync: function (odataSetName, filter, successCallback, errorCallback) {
///<summary>
/// Initiates an asynchronous request for the first 50 records of a given entity that meet the filter criteria
///</summary>
///<param name="odataSetName" type="String">
/// The name of the OData resource. For the Account entity, 'AccountSet'.
///</param>
///<param name="filter" type="String">
/// The OData system query options to limit the records returned or define which
/// attributes are returned. These are the query string parameters begining with '?'.
///</param>
///<param name="successCallback" type="Function">
/// The function to accept the array of records that are the result of a successful query.
///</param>
///<param name="errorCallback" type="Function">
/// The function to accept the error that is the result of an unsuccessful query.
///</param>
if (!odataSetName)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the odataSetName parameter"); }
if (!successCallback)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the successCallback parameter"); }
if (!errorCallback)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the errorCallback parameter"); }
var req = new XMLHttpRequest();
req.open("GET", this._ODataUrl() + "/" + odataSetName + filter, false);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
SDK.REST._retrieveMultipleResponse(this, successCallback, errorCallback);
};
req.send();
},
retrieveMultipleAsync: function (odataSetName, filter, successCallback, errorCallback) {
///<summary>
/// Initiates an asynchronous request for the first 50 records of a given entity that meet the filter criteria
///</summary>
///<param name="odataSetName" type="String">
/// The name of the OData resource. For the Account entity, 'AccountSet'.
///</param>
///<param name="filter" type="String">
/// The OData system query options to limit the records returned or define which
/// attributes are returned. These are the query string parameters begining with '?'.
///</param>
///<param name="successCallback" type="Function">
/// The function to accept the array of records that are the result of a successful query.
///</param>
///<param name="errorCallback" type="Function">
/// The function to accept the error that is the result of an unsuccessful query.
///</param>
if (!odataSetName)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the odataSetName parameter"); }
if (!successCallback)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the successCallback parameter"); }
if (!errorCallback)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the errorCallback parameter"); }
var req = new XMLHttpRequest();
req.open("GET", this._ODataUrl() + "/" + odataSetName + filter, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
SDK.REST._retrieveMultipleResponse(this, successCallback, errorCallback);
};
req.send();
},
_retrieveMultipleResponse: function (req, successCallback, errorCallback) {
///<summary>
/// Private function that processes the response from SDK.REST.retrieveMultipleAsync
///</summary>
///<param name="req" type="XMLHttpRequest">
/// The XMLHttpRequest representing the response.
///</param>
///<param name="successCallback" type="Function">
/// The function to accept the array of records that are the result of a successful query.
///</param>
///<param name="errorCallback" type="Function">
/// The function to accept the error that is the result of an unsuccessful query.
///</param>
if (req.readyState == 4 /* complete */) {
if (req.status == 200) {
//Success
successCallback(JSON.parse(req.responseText, SDK.REST.dateReviver).d.results);
}
else {
errorCallback(JSON.parse(req.responseText).error);
}
}
},
createAsync: function (odataSetName, object, successCallback, errorCallback) {
///<summary>
/// Initiates an asynchronous request to create a record for a given entity.
///</summary>
///<param name="odataSetName" type="String">
/// The name of the OData resource. For the Account entity, 'AccountSet'.
///</param>
///<param name="object" type="Object">
/// A JScript object containing valid properties for the entity.
///</param>
///<param name="successCallback" type="Function">
/// The function to accept the array of records that are the result of a successful query.
///</param>
///<param name="errorCallback" type="Function">
/// The function to accept the error that is the result of an unsuccessful query.
///</param>
var req = new XMLHttpRequest();
req.open("POST", this._ODataUrl() + "/" + odataSetName, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
SDK.REST._createResponse(this, successCallback, errorCallback);
};
req.send(JSON.stringify(object));
},
_createResponse: function (req, successCallback, errorCallback) {
///<summary>
/// Private function that processes the response from SDK.REST.createAsync
///</summary>
///<param name="req" type="XMLHttpRequest">
/// The XMLHttpRequest representing the response.
///</param>
///<param name="successCallback" type="Function">
/// The function to accept the object represnting the created record.
///</param>
///<param name="errorCallback" type="Function">
/// The function to accept the error that is the result of an unsuccessful attempt to create a record.
///</param>
if (req.readyState == 4 /* complete */) {
if (req.status == 201) {
//Success
successCallback(JSON.parse(req.responseText).d);
}
else {
errorCallback(JSON.parse(req.responseText).error);
}
}
},
updateAsync: function (odataSetName, object, id, successCallback, errorCallback) {
///<summary>
/// Initiates an asynchronous request to update a record for a given entity.
///</summary>
///<param name="odataSetName" type="String">
/// The name of the OData resource. For the Account entity, 'AccountSet'.
///</param>
///<param name="object" type="Object">
/// A JScript object containing valid properties for the entity.
///</param>
///<param name="id" type="String">
/// Provides the GUID unique identifier for the record to be updated.
///</param>
///<param name="successCallback" type="Function">
/// The function to acknowlege the successful completion of the update.
///</param>
///<param name="errorCallback" type="Function">
/// The function to accept the error that is the result of an unsuccessful update attempt.
///</param>
var req = new XMLHttpRequest();
req.open("POST", this._ODataUrl() + "/" + odataSetName + "(guid'" + id + "')", true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("X-HTTP-Method", "MERGE");
req.onreadystatechange = function () {
SDK.REST._updateResponse(this, successCallback, errorCallback);
};
req.send(JSON.stringify(object));
},
_updateResponse: function (req, successCallback, errorCallback) {
///<summary>
/// Private function that processes the response from SDK.REST.updateAsync
///</summary>
///<param name="req" type="XMLHttpRequest">
/// The XMLHttpRequest representing the response.
///</param>
///<param name="successCallback" type="Function">
/// The function to acknowlege the successful completion of the update.
///</param>
///<param name="errorCallback" type="Function">
/// The function to accept the error that is the result of an unsuccessful update attempt.
///</param>
if (req.readyState == 4 /* complete */) {
//There appears to be an issue where IE maps the 204 status to 1223 when no content is returned.
if (req.status == 204 || req.status == 1223) {
successCallback();
}
else {
errorCallback(JSON.parse(req.responseText).error);
}
}
},
deleteAsync: function (odataSetName, id, successCallback, errorCallback) {
///<summary>
/// Initiates an asynchronous request to delete a record for a given entity.
///</summary>
///<param name="odataSetName" type="String">
/// The name of the OData resource. For the Account entity, 'AccountSet'.
///</param>
///<param name="id" type="String">
/// Provides the GUID unique identifier for the record to be deleted.
///</param>
///<param name="successCallback" type="Function">
/// The function to acknowlege the successful deletion of the record.
///</param>
///<param name="errorCallback" type="Function">
/// The function to accept the error that is the result of an unsuccessful delete attempt.
///</param>
var req = new XMLHttpRequest();
req.open("POST", this._ODataUrl() + "/" + odataSetName + "(guid'" + id + "')", true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("X-HTTP-Method", "DELETE");
req.onreadystatechange = function () {
SDK.REST._deleteResponse(this, function () { successCallback(id) }, errorCallback);
};
req.send();
},
_deleteResponse: function (req, successCallback, errorCallback) {
///<summary>
/// Private function that processes the response from SDK.REST.deleteAsync
///</summary>
///<param name="req" type="XMLHttpRequest">
/// The XMLHttpRequest representing the response.
///</param>
///<param name="successCallback" type="Function">
/// The function to acknowlege the successful completion of the delete.
///</param>
///<param name="errorCallback" type="Function">
/// The function to accept the error that is the result of an unsuccessful delete attempt.
///</param>
if (req.readyState == 4 /* complete */) {
//There appears to be an issue where IE maps the 204 status to 1223 when no content is returned.
if (req.status == 204 || req.status == 1223) {
successCallback();
}
else {
errorCallback(JSON.parse(req.responseText).error);
}
}
},
retrieveSync: function (odataSetName, id, successCallback, errorCallback) {
///<summary>
/// function to retrieve a specific record.
///</summary>
if (!odataSetName)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the odataSetName parameter"); }
if (!id)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the id parameter"); }
if (!successCallback)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the successCallback parameter"); }
if (!errorCallback)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the errorCallback parameter"); }
var req = new XMLHttpRequest();
req.open("GET", this._ODataUrl() + "/" + odataSetName + "(guid'" + id + "')", false);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
SDK.REST._retrieveResponse(this, successCallback, errorCallback);
};
req.send();
},
retrieveAsync: function (odataSetName, id, successCallback, errorCallback) {
///<summary>
/// function to retrieve a specific record.
///</summary>
if (!odataSetName)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the odataSetName parameter"); }
if (!id)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the id parameter"); }
if (!successCallback)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the successCallback parameter"); }
if (!errorCallback)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the errorCallback parameter"); }
var req = new XMLHttpRequest();
req.open("GET", this._ODataUrl() + "/" + odataSetName + "(guid'" + id + "')", true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
SDK.REST._retrieveResponse(this, successCallback, errorCallback);
};
req.send();
},
_retrieveResponse: function (req, successCallback, errorCallback) {
///<summary>
/// function to retrieve the response from SDK.REST.retrieveAsync
///</summary>
if (req.readyState == 4 /* complete */) {
if (req.status == 200) {
//Success
successCallback(JSON.parse(req.responseText).d);
//successCallback(JSON.parse(req.responseText, SDK.REST.dateReviver).d.results);
}
else {
errorCallback(JSON.parse(req.responseText).error);
}
}
},
associateAsync: function (entity1Set, entity1Id, entity2Set, entity2Id, relationship, successCallback, errorCallback) {
///<summary>
/// Unimplemented function placeholder to associate a pair of records.
///</summary>
var entity2 = {};
entity2.uri = this._ODataUrl() + "/" + entity2Set + "(guid'" + entity2Id + "')";
var req = new XMLHttpRequest();
req.open("POST", this._ODataUrl() + "/" + entity1Set + "(guid'" + entity1Id + "')/$links/" + relationship, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
SDK.REST._associateResponse(this, successCallback, errorCallback);
};
req.send(JSON.stringify(entity2));
},
_associateResponse: function (req, successCallback, errorCallback) {
///<summary>
/// Unimplemented function placeholder to retrieve the response from SDK.REST.associateAsync
///</summary>
if (req.readyState == 4 /* complete */) {
//There appears to be an issue where IE maps the 204 status to 1223 when no content is returned.
if (req.status == 204 || req.status == 1223) {
successCallback();
}
else {
errorCallback(JSON.parse(req.responseText).error);
}
}
},
dissassociateAsync: function (entity1Set, entity1Id, entity2Id, relationship, successCallback, errorCallback) {
///<summary>
/// function to disassociate a pair of records.
///</summary>
var req = new XMLHttpRequest();
req.open("POST", this._ODataUrl() + "/" + entity1Set + "(guid'" + entity1Id + "')/$links/" + relationship + "(guid'" + entity2Id + "')", true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("X-HTTP-Method", "DELETE");
req.onreadystatechange = function () {
SDK.REST._disassociateResponse(this, successCallback, errorCallback);
};
req.send();
},
_disassociateResponse: function (req, successCallback, errorCallback) {
///<summary>
/// function to retrieve the response from SDK.REST.dissassociateAsync
///</summary>
if (req.readyState == 4 /* complete */) {
//There appears to be an issue where IE maps the 204 status to 1223 when no content is returned.
if (req.status == 204 || req.status == 1223) {
successCallback();
}
else {
errorCallback(JSON.parse(req.responseText).error);
}
}
},
dateReviver: function (key, value) {
///<summary>
/// A function to be used as a date reviver parameter to JSON.parse.
///</summary>
///<param name="key" type="String">
/// The key for the JSON object
///</param>
///<param name="value" type="Object">
/// The value for the JSON object
///</param>
var a;
if (typeof value === 'string') {
a = /Date\(([-+]?\d+)\)/.exec(value); //Matches "\/Date(1234567890123)\/ or "\/Date(-1234567890123)\/"
if (a) {
return new Date(parseInt(value.replace("/Date(", "").replace(")/", ""), 10));
}
}
return value;
},
//Sdk 2013
_stringParameterCheck: function (parameter, message) {
///<summary>
/// Private function used to check whether required parameters are null or undefined
///</summary>
///<param name="parameter" type="String">
/// The string parameter to check;
///</param>
///<param name="message" type="String">
/// The error message text to include when the error is thrown.
///</param>
if (typeof parameter != "string") {
throw new Error(message);
}
},
_callbackParameterCheck: function (callbackParameter, message) {
///<summary>
/// Private function used to check whether required callback parameters are functions
///</summary>
///<param name="callbackParameter" type="Function">
/// The callback parameter to check;
///</param>
///<param name="message" type="String">
/// The error message text to include when the error is thrown.
///</param>
if (typeof callbackParameter != "function") {
throw new Error(message);
}
},
_ODataPath: function () {
///<summary>
/// Private function to return the path to the REST endpoint.
///</summary>
///<returns>String</returns>
return this._getClientUrl() + "/XRMServices/2011/OrganizationData.svc/";
},
_context: function () {
///<summary>
/// Private function to the context object.
///</summary>
///<returns>Context</returns>
if (typeof GetGlobalContext != "undefined")
{ return GetGlobalContext(); }
else {
if (typeof Xrm != "undefined") {
return Xrm.Page.context;
}
else { throw new Error("Context is not available."); }
}
},
_getClientUrl: function () {
///<summary>
/// Private function to return the server URL from the context
///</summary>
///<returns>String</returns>
var clientUrl = this._context().getClientUrl()
return clientUrl;
},
_dateReviver: function (key, value) {
///<summary>
/// Private function to convert matching string values to Date objects.
///</summary>
///<param name="key" type="String">
/// The key used to identify the object property
///</param>
///<param name="value" type="String">
/// The string value representing a date
///</param>
var a;
if (typeof value === 'string') {
a = /Date\(([-+]?\d+)\)/.exec(value);
if (a) {
return new Date(parseInt(value.replace("/Date(", "").replace(")/", ""), 10));
}
}
return value;
},
_errorHandler: function (req) {
///<summary>
/// Private function return an Error object to the errorCallback
///</summary>
///<param name="req" type="XMLHttpRequest">
/// The XMLHttpRequest response that returned an error.
///</param>
///<returns>Error</returns>
//Error descriptions come from http://support.microsoft.com/kb/193625
if (req.status == 12029)
{ return new Error("The attempt to connect to the server failed."); }
if (req.status == 12007)
{ return new Error("The server name could not be resolved."); }
var errorText;
try
{ errorText = JSON.parse(req.responseText).error.message.value; }
catch (e)
{ errorText = req.responseText }
return new Error("Error : " +
req.status + ": " +
req.statusText + ": " + errorText);
},
retrieveMultipleRecords: function (type, options, successCallback, errorCallback, OnComplete) {
///<summary>
/// Sends an asynchronous request to retrieve records.
///</summary>
///<param name="type" type="String">
/// The Schema Name of the Entity type record to retrieve.
/// For an Account record, use "Account"
///</param>
///<param name="options" type="String">
/// A String representing the OData System Query Options to control the data returned
///</param>
///<param name="successCallback" type="Function">
/// The function that will be passed through and be called for each page of records returned.
/// Each page is 50 records. If you expect that more than one page of records will be returned,
/// this function should loop through the results and push the records into an array outside of the function.
/// Use the OnComplete event handler to know when all the records have been processed.
/// </param>
///<param name="errorCallback" type="Function">
/// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// </param>
///<param name="OnComplete" type="Function">
/// The function that will be called when all the requested records have been returned.
/// No parameters are passed to this function.
/// </param>
this._stringParameterCheck(type, "SDK.REST.retrieveMultipleRecords requires the type parameter is a string.");
if (options != null)
this._stringParameterCheck(options, "SDK.REST.retrieveMultipleRecords requires the options parameter is a string.");
this._callbackParameterCheck(successCallback, "SDK.REST.retrieveMultipleRecords requires the successCallback parameter is a function.");
this._callbackParameterCheck(errorCallback, "SDK.REST.retrieveMultipleRecords requires the errorCallback parameter is a function.");
this._callbackParameterCheck(OnComplete, "SDK.REST.retrieveMultipleRecords requires the OnComplete parameter is a function.");
var optionsString;
if (options != null) {
if (options.charAt(0) != "?") {
optionsString = "?" + options;
}
else { optionsString = options; }
}
var req = new XMLHttpRequest();
req.open("GET", this._ODataPath() + type + "Set" + optionsString, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 200) {
var returned = JSON.parse(this.responseText, SDK.REST._dateReviver).d;
successCallback(returned.results);
if (returned.__next != null) {
var queryOptions = returned.__next.substring((SDK.REST._ODataPath() + type + "Set").length);
SDK.REST.retrieveMultipleRecords(type, queryOptions, successCallback, errorCallback, OnComplete);
}
else { OnComplete(); }
}
else {
errorCallback(SDK.REST._errorHandler(this));
}
}
};
req.send();
},
__namespace: true
};
// This file is part of the Microsoft Dynamics CRM SDK code samples.
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
// This source code is intended only as a supplement to Microsoft
// Development Tools and/or on-line documentation. See these other
// materials for detailed information regarding Microsoft code samples.
//
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// =====================================================================
if (typeof (SDK) == "undefined")
{ SDK = { __namespace: true }; }
SDK.REST = {
_Context: function () {
///<summary>
/// Private function that retrieves the context from either the Xrm.Page.context
/// or the GetGlobalContext function in ClientGlobalContext.js.aspx
///</summary>
var errorMessage = "Context is not available.";
if (typeof GetGlobalContext != "undefined") {
return GetGlobalContext();
}
else if (typeof Xrm != "undefined") {
return Xrm.Page.context;
}
else if (typeof parent.Xrm.Page.context != "undefined") {
return parent.Xrm.Page.context;
}
else {
return new Error(errorMessage);
}
},
_ODataUrl: function () {
///<summary>
/// Private function composes the OData URL using the _Context object.
///</summary>
//Detect if the hostname is an IP address then we return the IP address as the server destination instead of the server name (which will be unfound)
var urlReg = new RegExp(/http[s]?:\/\/[0-9.:]+\/[a-zA-Z0-9.-_~]+/i);
var ServerUrl = this._Context().getServerUrl();
if (window.location.href.match(urlReg) != null) {
ServerUrl = window.location.href.match(urlReg).toString();
}
if (ServerUrl.match(/\/$/)) {
ServerUrl = ServerUrl.substring(0, ServerUrl.length - 1);
}
return ServerUrl + "/XRMServices/2011/OrganizationData.svc";
},
retrieveMultipleSync: function (odataSetName, filter, successCallback, errorCallback) {
///<summary>
/// Initiates an asynchronous request for the first 50 records of a given entity that meet the filter criteria
///</summary>
///<param name="odataSetName" type="String">
/// The name of the OData resource. For the Account entity, 'AccountSet'.
///</param>
///<param name="filter" type="String">
/// The OData system query options to limit the records returned or define which
/// attributes are returned. These are the query string parameters begining with '?'.
///</param>
///<param name="successCallback" type="Function">
/// The function to accept the array of records that are the result of a successful query.
///</param>
///<param name="errorCallback" type="Function">
/// The function to accept the error that is the result of an unsuccessful query.
///</param>
if (!odataSetName)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the odataSetName parameter"); }
if (!successCallback)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the successCallback parameter"); }
if (!errorCallback)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the errorCallback parameter"); }
var req = new XMLHttpRequest();
req.open("GET", this._ODataUrl() + "/" + odataSetName + filter, false);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
SDK.REST._retrieveMultipleResponse(this, successCallback, errorCallback);
};
req.send();
},
retrieveMultipleAsync: function (odataSetName, filter, successCallback, errorCallback) {
///<summary>
/// Initiates an asynchronous request for the first 50 records of a given entity that meet the filter criteria
///</summary>
///<param name="odataSetName" type="String">
/// The name of the OData resource. For the Account entity, 'AccountSet'.
///</param>
///<param name="filter" type="String">
/// The OData system query options to limit the records returned or define which
/// attributes are returned. These are the query string parameters begining with '?'.
///</param>
///<param name="successCallback" type="Function">
/// The function to accept the array of records that are the result of a successful query.
///</param>
///<param name="errorCallback" type="Function">
/// The function to accept the error that is the result of an unsuccessful query.
///</param>
if (!odataSetName)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the odataSetName parameter"); }
if (!successCallback)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the successCallback parameter"); }
if (!errorCallback)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the errorCallback parameter"); }
var req = new XMLHttpRequest();
req.open("GET", this._ODataUrl() + "/" + odataSetName + filter, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
SDK.REST._retrieveMultipleResponse(this, successCallback, errorCallback);
};
req.send();
},
_retrieveMultipleResponse: function (req, successCallback, errorCallback) {
///<summary>
/// Private function that processes the response from SDK.REST.retrieveMultipleAsync
///</summary>
///<param name="req" type="XMLHttpRequest">
/// The XMLHttpRequest representing the response.
///</param>
///<param name="successCallback" type="Function">
/// The function to accept the array of records that are the result of a successful query.
///</param>
///<param name="errorCallback" type="Function">
/// The function to accept the error that is the result of an unsuccessful query.
///</param>
if (req.readyState == 4 /* complete */) {
if (req.status == 200) {
//Success
successCallback(JSON.parse(req.responseText, SDK.REST.dateReviver).d.results);
}
else {
errorCallback(JSON.parse(req.responseText).error);
}
}
},
createAsync: function (odataSetName, object, successCallback, errorCallback) {
///<summary>
/// Initiates an asynchronous request to create a record for a given entity.
///</summary>
///<param name="odataSetName" type="String">
/// The name of the OData resource. For the Account entity, 'AccountSet'.
///</param>
///<param name="object" type="Object">
/// A JScript object containing valid properties for the entity.
///</param>
///<param name="successCallback" type="Function">
/// The function to accept the array of records that are the result of a successful query.
///</param>
///<param name="errorCallback" type="Function">
/// The function to accept the error that is the result of an unsuccessful query.
///</param>
var req = new XMLHttpRequest();
req.open("POST", this._ODataUrl() + "/" + odataSetName, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
SDK.REST._createResponse(this, successCallback, errorCallback);
};
req.send(JSON.stringify(object));
},
_createResponse: function (req, successCallback, errorCallback) {
///<summary>
/// Private function that processes the response from SDK.REST.createAsync
///</summary>
///<param name="req" type="XMLHttpRequest">
/// The XMLHttpRequest representing the response.
///</param>
///<param name="successCallback" type="Function">
/// The function to accept the object represnting the created record.
///</param>
///<param name="errorCallback" type="Function">
/// The function to accept the error that is the result of an unsuccessful attempt to create a record.
///</param>
if (req.readyState == 4 /* complete */) {
if (req.status == 201) {
//Success
successCallback(JSON.parse(req.responseText).d);
}
else {
errorCallback(JSON.parse(req.responseText).error);
}
}
},
updateAsync: function (odataSetName, object, id, successCallback, errorCallback) {
///<summary>
/// Initiates an asynchronous request to update a record for a given entity.
///</summary>
///<param name="odataSetName" type="String">
/// The name of the OData resource. For the Account entity, 'AccountSet'.
///</param>
///<param name="object" type="Object">
/// A JScript object containing valid properties for the entity.
///</param>
///<param name="id" type="String">
/// Provides the GUID unique identifier for the record to be updated.
///</param>
///<param name="successCallback" type="Function">
/// The function to acknowlege the successful completion of the update.
///</param>
///<param name="errorCallback" type="Function">
/// The function to accept the error that is the result of an unsuccessful update attempt.
///</param>
var req = new XMLHttpRequest();
req.open("POST", this._ODataUrl() + "/" + odataSetName + "(guid'" + id + "')", true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("X-HTTP-Method", "MERGE");
req.onreadystatechange = function () {
SDK.REST._updateResponse(this, successCallback, errorCallback);
};
req.send(JSON.stringify(object));
},
_updateResponse: function (req, successCallback, errorCallback) {
///<summary>
/// Private function that processes the response from SDK.REST.updateAsync
///</summary>
///<param name="req" type="XMLHttpRequest">
/// The XMLHttpRequest representing the response.
///</param>
///<param name="successCallback" type="Function">
/// The function to acknowlege the successful completion of the update.
///</param>
///<param name="errorCallback" type="Function">
/// The function to accept the error that is the result of an unsuccessful update attempt.
///</param>
if (req.readyState == 4 /* complete */) {
//There appears to be an issue where IE maps the 204 status to 1223 when no content is returned.
if (req.status == 204 || req.status == 1223) {
successCallback();
}
else {
errorCallback(JSON.parse(req.responseText).error);
}
}
},
deleteAsync: function (odataSetName, id, successCallback, errorCallback) {
///<summary>
/// Initiates an asynchronous request to delete a record for a given entity.
///</summary>
///<param name="odataSetName" type="String">
/// The name of the OData resource. For the Account entity, 'AccountSet'.
///</param>
///<param name="id" type="String">
/// Provides the GUID unique identifier for the record to be deleted.
///</param>
///<param name="successCallback" type="Function">
/// The function to acknowlege the successful deletion of the record.
///</param>
///<param name="errorCallback" type="Function">
/// The function to accept the error that is the result of an unsuccessful delete attempt.
///</param>
var req = new XMLHttpRequest();
req.open("POST", this._ODataUrl() + "/" + odataSetName + "(guid'" + id + "')", true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("X-HTTP-Method", "DELETE");
req.onreadystatechange = function () {
SDK.REST._deleteResponse(this, function () { successCallback(id) }, errorCallback);
};
req.send();
},
_deleteResponse: function (req, successCallback, errorCallback) {
///<summary>
/// Private function that processes the response from SDK.REST.deleteAsync
///</summary>
///<param name="req" type="XMLHttpRequest">
/// The XMLHttpRequest representing the response.
///</param>
///<param name="successCallback" type="Function">
/// The function to acknowlege the successful completion of the delete.
///</param>
///<param name="errorCallback" type="Function">
/// The function to accept the error that is the result of an unsuccessful delete attempt.
///</param>
if (req.readyState == 4 /* complete */) {
//There appears to be an issue where IE maps the 204 status to 1223 when no content is returned.
if (req.status == 204 || req.status == 1223) {
successCallback();
}
else {
errorCallback(JSON.parse(req.responseText).error);
}
}
},
retrieveSync: function (odataSetName, id, successCallback, errorCallback) {
///<summary>
/// function to retrieve a specific record.
///</summary>
if (!odataSetName)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the odataSetName parameter"); }
if (!id)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the id parameter"); }
if (!successCallback)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the successCallback parameter"); }
if (!errorCallback)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the errorCallback parameter"); }
var req = new XMLHttpRequest();
req.open("GET", this._ODataUrl() + "/" + odataSetName + "(guid'" + id + "')", false);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
SDK.REST._retrieveResponse(this, successCallback, errorCallback);
};
req.send();
},
retrieveAsync: function (odataSetName, id, successCallback, errorCallback) {
///<summary>
/// function to retrieve a specific record.
///</summary>
if (!odataSetName)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the odataSetName parameter"); }
if (!id)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the id parameter"); }
if (!successCallback)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the successCallback parameter"); }
if (!errorCallback)
{ throw new Error("SDK.REST.retrieveMultipleAsync requires the errorCallback parameter"); }
var req = new XMLHttpRequest();
req.open("GET", this._ODataUrl() + "/" + odataSetName + "(guid'" + id + "')", true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
SDK.REST._retrieveResponse(this, successCallback, errorCallback);
};
req.send();
},
_retrieveResponse: function (req, successCallback, errorCallback) {
///<summary>
/// function to retrieve the response from SDK.REST.retrieveAsync
///</summary>
if (req.readyState == 4 /* complete */) {
if (req.status == 200) {
//Success
successCallback(JSON.parse(req.responseText).d);
//successCallback(JSON.parse(req.responseText, SDK.REST.dateReviver).d.results);
}
else {
errorCallback(JSON.parse(req.responseText).error);
}
}
},
associateAsync: function (entity1Set, entity1Id, entity2Set, entity2Id, relationship, successCallback, errorCallback) {
///<summary>
/// Unimplemented function placeholder to associate a pair of records.
///</summary>
var entity2 = {};
entity2.uri = this._ODataUrl() + "/" + entity2Set + "(guid'" + entity2Id + "')";
var req = new XMLHttpRequest();
req.open("POST", this._ODataUrl() + "/" + entity1Set + "(guid'" + entity1Id + "')/$links/" + relationship, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
SDK.REST._associateResponse(this, successCallback, errorCallback);
};
req.send(JSON.stringify(entity2));
},
_associateResponse: function (req, successCallback, errorCallback) {
///<summary>
/// Unimplemented function placeholder to retrieve the response from SDK.REST.associateAsync
///</summary>
if (req.readyState == 4 /* complete */) {
//There appears to be an issue where IE maps the 204 status to 1223 when no content is returned.
if (req.status == 204 || req.status == 1223) {
successCallback();
}
else {
errorCallback(JSON.parse(req.responseText).error);
}
}
},
dissassociateAsync: function (entity1Set, entity1Id, entity2Id, relationship, successCallback, errorCallback) {
///<summary>
/// function to disassociate a pair of records.
///</summary>
var req = new XMLHttpRequest();
req.open("POST", this._ODataUrl() + "/" + entity1Set + "(guid'" + entity1Id + "')/$links/" + relationship + "(guid'" + entity2Id + "')", true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("X-HTTP-Method", "DELETE");
req.onreadystatechange = function () {
SDK.REST._disassociateResponse(this, successCallback, errorCallback);
};
req.send();
},
_disassociateResponse: function (req, successCallback, errorCallback) {
///<summary>
/// function to retrieve the response from SDK.REST.dissassociateAsync
///</summary>
if (req.readyState == 4 /* complete */) {
//There appears to be an issue where IE maps the 204 status to 1223 when no content is returned.
if (req.status == 204 || req.status == 1223) {
successCallback();
}
else {
errorCallback(JSON.parse(req.responseText).error);
}
}
},
dateReviver: function (key, value) {
///<summary>
/// A function to be used as a date reviver parameter to JSON.parse.
///</summary>
///<param name="key" type="String">
/// The key for the JSON object
///</param>
///<param name="value" type="Object">
/// The value for the JSON object
///</param>
var a;
if (typeof value === 'string') {
a = /Date\(([-+]?\d+)\)/.exec(value); //Matches "\/Date(1234567890123)\/ or "\/Date(-1234567890123)\/"
if (a) {
return new Date(parseInt(value.replace("/Date(", "").replace(")/", ""), 10));
}
}
return value;
},
//Sdk 2013
_stringParameterCheck: function (parameter, message) {
///<summary>
/// Private function used to check whether required parameters are null or undefined
///</summary>
///<param name="parameter" type="String">
/// The string parameter to check;
///</param>
///<param name="message" type="String">
/// The error message text to include when the error is thrown.
///</param>
if (typeof parameter != "string") {
throw new Error(message);
}
},
_callbackParameterCheck: function (callbackParameter, message) {
///<summary>
/// Private function used to check whether required callback parameters are functions
///</summary>
///<param name="callbackParameter" type="Function">
/// The callback parameter to check;
///</param>
///<param name="message" type="String">
/// The error message text to include when the error is thrown.
///</param>
if (typeof callbackParameter != "function") {
throw new Error(message);
}
},
_ODataPath: function () {
///<summary>
/// Private function to return the path to the REST endpoint.
///</summary>
///<returns>String</returns>
return this._getClientUrl() + "/XRMServices/2011/OrganizationData.svc/";
},
_context: function () {
///<summary>
/// Private function to the context object.
///</summary>
///<returns>Context</returns>
if (typeof GetGlobalContext != "undefined")
{ return GetGlobalContext(); }
else {
if (typeof Xrm != "undefined") {
return Xrm.Page.context;
}
else { throw new Error("Context is not available."); }
}
},
_getClientUrl: function () {
///<summary>
/// Private function to return the server URL from the context
///</summary>
///<returns>String</returns>
var clientUrl = this._context().getClientUrl()
return clientUrl;
},
_dateReviver: function (key, value) {
///<summary>
/// Private function to convert matching string values to Date objects.
///</summary>
///<param name="key" type="String">
/// The key used to identify the object property
///</param>
///<param name="value" type="String">
/// The string value representing a date
///</param>
var a;
if (typeof value === 'string') {
a = /Date\(([-+]?\d+)\)/.exec(value);
if (a) {
return new Date(parseInt(value.replace("/Date(", "").replace(")/", ""), 10));
}
}
return value;
},
_errorHandler: function (req) {
///<summary>
/// Private function return an Error object to the errorCallback
///</summary>
///<param name="req" type="XMLHttpRequest">
/// The XMLHttpRequest response that returned an error.
///</param>
///<returns>Error</returns>
//Error descriptions come from http://support.microsoft.com/kb/193625
if (req.status == 12029)
{ return new Error("The attempt to connect to the server failed."); }
if (req.status == 12007)
{ return new Error("The server name could not be resolved."); }
var errorText;
try
{ errorText = JSON.parse(req.responseText).error.message.value; }
catch (e)
{ errorText = req.responseText }
return new Error("Error : " +
req.status + ": " +
req.statusText + ": " + errorText);
},
retrieveMultipleRecords: function (type, options, successCallback, errorCallback, OnComplete) {
///<summary>
/// Sends an asynchronous request to retrieve records.
///</summary>
///<param name="type" type="String">
/// The Schema Name of the Entity type record to retrieve.
/// For an Account record, use "Account"
///</param>
///<param name="options" type="String">
/// A String representing the OData System Query Options to control the data returned
///</param>
///<param name="successCallback" type="Function">
/// The function that will be passed through and be called for each page of records returned.
/// Each page is 50 records. If you expect that more than one page of records will be returned,
/// this function should loop through the results and push the records into an array outside of the function.
/// Use the OnComplete event handler to know when all the records have been processed.
/// </param>
///<param name="errorCallback" type="Function">
/// The function that will be passed through and be called by a failed response.
/// This function must accept an Error object as a parameter.
/// </param>
///<param name="OnComplete" type="Function">
/// The function that will be called when all the requested records have been returned.
/// No parameters are passed to this function.
/// </param>
this._stringParameterCheck(type, "SDK.REST.retrieveMultipleRecords requires the type parameter is a string.");
if (options != null)
this._stringParameterCheck(options, "SDK.REST.retrieveMultipleRecords requires the options parameter is a string.");
this._callbackParameterCheck(successCallback, "SDK.REST.retrieveMultipleRecords requires the successCallback parameter is a function.");
this._callbackParameterCheck(errorCallback, "SDK.REST.retrieveMultipleRecords requires the errorCallback parameter is a function.");
this._callbackParameterCheck(OnComplete, "SDK.REST.retrieveMultipleRecords requires the OnComplete parameter is a function.");
var optionsString;
if (options != null) {
if (options.charAt(0) != "?") {
optionsString = "?" + options;
}
else { optionsString = options; }
}
var req = new XMLHttpRequest();
req.open("GET", this._ODataPath() + type + "Set" + optionsString, true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.onreadystatechange = function () {
if (this.readyState == 4 /* complete */) {
req.onreadystatechange = null;
if (this.status == 200) {
var returned = JSON.parse(this.responseText, SDK.REST._dateReviver).d;
successCallback(returned.results);
if (returned.__next != null) {
var queryOptions = returned.__next.substring((SDK.REST._ODataPath() + type + "Set").length);
SDK.REST.retrieveMultipleRecords(type, queryOptions, successCallback, errorCallback, OnComplete);
}
else { OnComplete(); }
}
else {
errorCallback(SDK.REST._errorHandler(this));
}
}
};
req.send();
},
__namespace: true
};
No comments:
Post a Comment