分享方式:


使用 OData 端點搭配 AJAX 和 JScript Web 資源

 

發佈日期: 2016年11月

適用對象: Dynamics CRM 2015

OData 端點讓您使用 JavaScript 程式庫與 Microsoft Dynamics CRM 2015 和 Microsoft Dynamics CRM Online 2015 更新 資料互動。 您使用檔案定義 JavaScript 程式庫建立指令碼 Web 資源。 然後您用表單或欄位事件常式或功能區命令動作關聯程式庫內的函數。 您可以依需要使用任何網頁 (HTML) Web 資源的其他 JavaScript 程式庫。

本主題內容

AJAX

經由張貼的方法

存取伺服器 URL

使用 XMLHttpRequest

使用 jQuery

使用日期

AJAX

AJAX (非同步 JavaScript 和 XML) 是用來建立互動式 Web 應用程式的 Web 開發技術。 伺服器請求是由位於背景的瀏覽器所建立,使用的是 XmlHttpRequest 物件。 雖然您可以傳送同步處理要求,建議的作法是傳送非同步要求。 非同步要求需要兩個 JScript 函數,第一個會送出請求,第二個則「回撥」則函數來處理回覆。

JSON

JavaScript 物件標記法 (JSON) 格式用來序列化並傳送結構資料,方式很類似 XML。 就像 XML,它是文字類型,而且設計可讓人類讀懂。 若要將一般的 JavaScript 物件轉換成 JSON 格式,您要使用 JSON.stringify 方法。 因為 JSON 中的文字定義 JavaScript 物件,文字會被轉換為 JavaScript 物件,使用的是 eval 方法。 不過,此作法會有安全性弱點。 您應使用 JSON.parse 方法。

XmlHttpRequest

XmlHttpRequest (有時候參照為 XHR) 提供設定以及傳送要求和定義回撥函數的功能,如這是非同步的請求。 來自伺服器的 HTTP 回覆包括狀態碼,指出要求是否成功。HTTP 狀態碼的值在 200 範圍內時,視為成功。

XmlHttpRequest 提供關於任何包含於回覆中的資料格式的指示到伺服器。 因為 ODATA 端點支援 ATOM 以及 JSON 格式,您可以使用選項請求資料用 XMLATOM 格式回傳。 不過,因為使用 JavaScript 程式碼,預期的一般請求會使用 JSON,因為使用 JavaScript 的話,很容易就會消耗掉。

經由張貼的方法

OData 協定用的是較不常見的 HTTP 動詞命令 PUT 以及 DELETE,以及定義新的動詞命令MERGE。 依照您使用的支援程式庫,您可能會在使用這些動詞命令時遇到問題。 要解決此問題的方法,就是使用 POST 動詞命令並用所要使用的動作來指定一個 X-HTTP-MethodHTTP 標題。 使用 setRequestHeader 方法來覆寫指定於 XmlHttpRequest 的動作。

存取伺服器 URL

當您開始使用 JavaScript 來建立 ODATA 時,第一件要做的事就是建立 URL 至組織基礎 URL。 使用內容物件的 getClientUrl 函數。

使用 XMLHttpRequest

jQuery 是一種具有多種功能的優秀程式庫,但是使用jQuery 並非執行作業 (使用 ODATAMicrosoft Dynamics 365 端點) 的先決條件。 我們建議您不要使用表單指令碼中的 jQuery 或是在應用程式頁面中執行的命令指令碼,請用直接使用 XmlHttpRequest 並避免載入 jQuery 程式庫。jQuery**$.ajax** 使用瀏覽器中可用的 XmlHttpRequest。 直接使用此物件和使用 $.ajax 有一點不同。 如果已使用熟悉使用 XMLHttpRequest,您應繼續使用它。 如果您一直使用 jQuery,之後請直接考慮使用 XMLHttpRequest。其他資訊:XMLHttpRequest 物件

具有 XmlHttpRequest,您會為 onreadystatechange 事件建立一個事件處理常式並偵測。 在事件處理常式中,請檢查回傳的狀態碼來判斷請求是否成功。 最後,請使用 opensend 方法。 下列範例使用 XmlHttpRequest 建立新的客戶記錄。

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);
        }
    }
};

如需其他使用 XMLHttpRequest 的範例,請參閱 範例:使用 OData 端點和 JavaScript 建立、擷取、更新及刪除

使用 jQuery

jQuery 是常用的 JavaScript 程式庫,包含在 Microsoft Visual Studio Web 應用程式專案中。jQuery 提供一種物件的擴充架構與函數,讓您查詢並使用 JavaScript 來與 HTML 一起使用。 若要使用 XMLHttpRequest,jQuery 提供 jQuery.ajax 方法。

備註

我們不建議將 jQuery 和表單指令碼或命令一起使用。其他資訊:使用 jQuery

jQuery 物件已使用 $ 字元建立參照,所以 jQuery.ajax 的簡易格式是 $.ajaxajax 方法通常在適當語法下使用,然後在物件項化時傳送要求。 下列範例建立新的客戶記錄。

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);
    }
});

下表列出您應該知道的屬性來處理 HTTP 請求,並針對 Microsoft Dynamics 365 使用 ODATA 端點來回覆。

屬性名稱

類型

註解

type

string

針對所有作業擷取資料與 POST 時,請使用 GET。其他資訊:明確設定此要求頁首為不同的 HTTP 動作

contentType

string

指定傳送至伺服器的內容類型。 當您用 JSON 格式傳送時,請使用 application/json; charset=utf-8。

dataType

string

預期伺服器傳回的資料類型。 使用json。

備註

簡易設定此屬性可能會不足。其他資訊:明確設定此要求頁首來接受 JSON

data

object

將此項目設定至 JSON 物件的值,來建立或更新作業。

url

string

ODATA 端點 URL 適用於您正在執行的動作。

beforeSend

function

一個讓您再傳送前先修改 XMLHttpRequest 物件的函數。

success

function

一個請求成功時的回撥函數。其他資訊:處理結果

error

function

一個請求失敗時呼叫的函數。其他資訊:處理錯誤

如需詳細資訊,請參閱範例:使用 OData 端點和 JavaScript 及 jQuery,建立、擷取、更新及刪除

明確設定此要求頁首來接受 JSON

當您在預期 JSON 格式的結果時,只設定 dataType 屬性將不會有效。 您可以使用 beforeSend 屬性明確設定 XMLHttpRequest 的標題來回傳資料為 JSON。 此動作一般來說會透過使用匿名函數執行,如同下列範例顯示。

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

當受到指定時,任何在 XMLHttpRequest.responseText 中的錯誤會在 JSON 中被格式化,而非在 XML 中。

提示

即使你不期待任何資料回傳,指定該結果一定會使用 JSON 回傳,簡化錯誤處理的過程。其他資訊:處理錯誤

明確設定此要求頁首為不同的 HTTP 動作

如 經由張貼的方法 所述,在您執行需要 HTTP 的動作而非 POSTGET 時,請使用 POSTbeforeSend 屬性,在 XMLHttpRequest 明確設定頁首來執行不同的動作。 此動作一般來說會透過使用匿名函數執行,如同下列範例顯示。

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

處理錯誤

在請求未成功時,$.ajax 會傳遞以下三種引數至錯誤屬性設定的函數。

  • XMLHttpRequest
    XMLHttpRequest 物件。

  • textStatus
    一個描述發生錯誤類型的字串。 可能的值如下:

    • null

    • timeout

    • error

    • notmodified

    • parsererror

  • errorThrown
    一個非預期的例外物件。

下列範例顯示如何將這些引數傳遞至管理錯誤的中央函數。

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

以下範例顯示用簡易的函數擷取錯誤訊息,並用 showMessage 函數顯示結果。

備註

此函數預期任何錯誤詳記資訊都會以 JSON 格式回傳。 除非 $.ajax 方法設定使用 JSON 回傳結果,XMLHttpRequest.responseText 將會是 XML。

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

處理結果

當您執行 POSTGET 作業時,您可預期資料回傳。 如果您指定結果使用 JSON 格式,傳回的結果會是 d 資料屬性。 當你建立或擷取使用獨特辨識工具紀錄,d 會針對紀錄顯示資料。 在某些案例中 d 會是陣列。

下列範例顯示處理傳回多筆客戶紀錄的查詢結果。

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

使用日期

有四項包含日期的任務需要執行:

  • 剖析擷取資料

  • 顯示日期值

  • 更新日期值

  • 設定日期為查詢篩選準則

剖析擷取資料

當您使用 ODATA 端點擷取紀錄時,日期值會以使用「\/Date(<ticks>)\/」格式的字串回傳,其中 <ticks> 是指 1970 年 1 月 1 日後毫秒的數字。 例如:"\/Date(1311170400000)\/"。 所有從 Microsoft Dynamics 365 回傳的值代表國際標準時間 (UTC) 的值,因此不會包括補償資訊。

以下有兩種策略供您使用 ODATA 端點剖析回傳紀錄中的日期:

  • 使用擁有 JSON.parse 的刺激函數

  • 請使用 String.replace 從字串建立日期值

使用擁有 JSON.parse 的刺激函數

JSON.parse 方法支援選用的刺激引數 (如 MSDN 的 JSON.parse 方法紀錄所述)。 以下為一項範例,它將符合定義在一般運算式型態的字串轉換成 Date 物件。

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;
};

備註

此碼假設日期值一定會為 UTC 日期值,且不會包含任何補償資訊。

請使用 String.replace 從字串建立日期值

如果您不使用 JSON.parse 方法的刺激引數,下列範例顯示如何從一個字串產生 Date 值。

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

顯示日期值

在此字串日期值轉換為 Date 物件後,您可以使用多種 JavaScript 方法,或是建立您自己的方法,在使用者介面中顯示字串形式的日期。 因為 JavaScriptDate 物件會查知 UTC,使用例如 toStringtoLocaleString 方法,將日期顯示在使用者介面中,將會依照使用者在作業系統中的時區設定呈現。

不過,請注意在應用程式中顯示的值,會和 Microsoft Dynamics 365 中顯示的值不同,這不會依照使用者的作業系統時區設定。 當使用者目前的操作系統時區偏好設定,與儲存在 Microsoft Dynamics 365 中的時區偏好設定不同的時候,這些值也會不同。Microsoft Dynamics 365 也允許設定個人化的呈現選項,但不會因為透過使用標準的 JavaScript 日期函數,例如 toString 而套用。

若要調整顯示的日期和時間值符合 Microsoft Dynamics 365 顯示的值,您可以查詢儲存在 UserSettings 實體中的查詢資料,且像是 TimeZoneDefinitionTimeZoneRule 這樣的實體來建立函數來顯示符合使用者偏好的日期。Microsoft Dynamics 365 不會提供函數來執行這些動作。

更新日期值

當您使用如 setMinutessetHours 這類的標準設定方法變更 JavaScript 日期的值,這些變更會用於使用者的當地時間中。 當您儲存記錄時,實際 UTC 值會序列化並回存到 Microsoft Dynamics 365。 您不需要執行任何動作來將日期轉換成 UTC 值。

Date 序列化時,該格式會因為資料擷取時用的格式而不同。 如同 剖析擷取資料中的說明,將會擷取日期,並使用 "\/Date(1311179400000)\/"的格式的字串顯示。 當您檢查要傳回伺服器的日期值 JSON.stringify 結果時,格式為 "2013-07-20T16:30:00Z".

設定日期為查詢篩選準則

當您使用 $filter 系統查詢選項,您必須使用 UTC 日期。 如要轉換 JavaScriptDate 物件為篩選預期的格式,您必須使用以下範例的函數來處理日期。 結果為符合以下格式的字串: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;
}

另請參閱

使用 OData 端點搭配 Web 資源
OData endpoint Http status codes
Microsoft Dynamics CRM 2015 適用的 JavaScript 程式庫
指令碼 (JScript) Web 資源
關聯函數與表單和欄位事件
jQuery.ajax 方法
XMLHttpRequest 物件
技術文章:使用選項組選項與 ODATA 端點 - JScript

© 2017 Microsoft. 著作權所有,並保留一切權利。 著作權