与 Ajax 和 JScript Web 资源一起使用 OData 终结点

 

发布日期: 2016年11月

适用于: Dynamics CRM 2015

通过 OData 端点,您可以使用 JavaScript 库与 Microsoft Dynamics CRM 2015 和 Microsoft Dynamics CRM Online 2015 更新 数据进行交互。 您可以使用用于定义 JavaScript 库的文件创建脚本 Web 资源。 然后将库中的函数与窗体、字段事件处理程序或功能区命令操作相关联。 您可以像使用网页 (HTML) Web 资源中的任何其他 JavaScript 库那样使用它们。

本主题内容

Ajax

通过 POST 对方法进行隧道处理

访问服务器 URL

使用 XmlHttpRequest

使用 jQuery

有关日期的操作

Ajax

AJAX(异步 JavaScript 和 XML)是用于创建交互式 Web 应用程序的 Web 开发技术。 服务器请求是使用 XmlHttpRequest 对象在后台从浏览器发出的。 尽管您可以发送同步请求,但建议的做法是发送异步请求。 异步请求需要两个 JScript 函数:一个用于发送请求,另一个用于“回调”函数以处理响应。

JSON

JavaScript 对象表示 (JSON) 格式用于序列化和传输结构化数据,操作方式与通常使用 XML 的方式大致相同。 与 XML 一样,它基于文本并具有可读性。 若要将常规 JavaScript 对象转换为 JSON 格式,请使用 JSON.stringify 方法。 因为 JSON 中的文本定义 JavaScript 对象,所以可以使用 eval 方法将文本转换为 JavaScript 对象。 但是,这种做法会导致安全隐患。 您应该改用 JSON.parse 方法。

XmlHttpRequest

如果是异步请求,则 XmlHttpRequest(有时称为 XHR)可提供配置和发送请求以及定义回调函数的功能。 来自服务器的 HTTP 响应包含指示请求是否成功的状态代码。 如果 HTTP 状态代码值在 200 范围内,则认为请求成功。

XmlHttpRequest 向服务器提供包含在响应中的所有数据的格式说明。 因为 ODATA 终结点同时支持 ATOM 和 JSON 格式,所以您可以选择请求数据以 XMLATOM 格式返回。 但是,对于 JavaScript 代码,预期的典型请求将使用 JSON,因为它很容易使用 JavaScript 处理。

通过 POST 对方法进行隧道处理

OData 协议使用不太常见的 HTTP 动词 PUTDELETE 并定义了一个新动词:MERGE。 根据您使用的支持库,您可能会在使用这些动词时遇到问题。 解决方法是使用 POST 动词,并伴随所需操作指定一个 X-HTTP-MethodHTTP 标头。 使用 setRequestHeader 方法可以覆盖在 XmlHttpRequest 中指定的操作。

访问服务器 URL

开始将 ODATA 终结点与 JavaScript 一起使用时,首先要建立指向组织根 URL 的 URL。 在上下文对象中可以使用 getClientUrl 函数。

使用 XmlHttpRequest

jQuery 是一个功能强大且用途广泛的库,但使用 Microsoft Dynamics 365 的 ODATA 端点执行操作时不一定要使用 jQuery。 我们建议您不要在应用程序页中运行的窗体脚本或命令脚本中使用 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 是 Microsoft Visual Studio 中的 Web 应用程序项目附带的常用 JavaScript 库。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);
    }
});

下表列出使用 Microsoft Dynamics 365 的 ODATA 终结点处理 HTTP 请求和响应时必须了解的属性。

属性名称

类型​​

注释

type

string

检索数据时使用 GET,对于所有其他操作使用 POST。详细信息:将请求头显式设置为其他 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 操作

如 通过 POST 对方法进行隧道处理 中所述的,如果所执行的操作需要 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 端点返回的记录中的日期:

  • 将 Reviver 函数与 JSON.parse 方法结合使用

  • 使用 String.replace 从字符串生成日期值

将 Reviver 函数与 JSON.parse 方法结合使用

JSON.parse 方法支持可选的 reviver 参数,如 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 从字符串生成日期值

如果不将 reviver 参数用于 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。 保留所有权利。 版权