在新窗口中打开的Web资源中使用Xrm.WebApi方法

时间:2018-07-19 07:13:05

标签: javascript dynamics-crm microsoft-dynamics dynamics-365 dynamics-crm-webapi

我使用以下命令在新窗口中打开了HTML网络资源:

Xrm.Navigation.openWebResource(webResource, windowOptions, data);

这是HTML Web资源,它正在将ClientObject加载到头部

<script type="text/javascript" src="../../../ClientGlobalContext.js.aspx" ></script>

然后我有一些JavaScript正在尝试检索Contact

var contactId = "8553DA63-11C9-E711-A824-000D3AE0CB84";
var promise = Xrm.WebApi.retrieveRecord("contact", contactId, "$select=contactid,firstname,lastname");`

但这是失败。我已逐步跟踪到Xrm.WebApi方法,发现错误是当它尝试将"contact"解析为Set Name

时出现的错误
  

Global.ashx

中的代码
getEntitySetName: function(logicalName) {
    Mscrm.Utilities.addTelemetryLog("Xrm.Utility.getEntitySetName");
    var $v_0 = window.ENTITY_SET_NAMES || window.top.ENTITY_SET_NAMES;
    if (IsNull(this.$5H_1) && !isNullOrEmptyString($v_0))
        this.$5H_1 = JSON.parse($v_0);
    return this.$5H_1[logicalName.toLowerCase()]
},

由于某种原因window.ENTITY_SET_NAMES对象为null,因此发生错误(空引用)

我尝试将我的Web资源嵌入到CRM页面中,并且代码可以正常工作。问题似乎出在通过Xrm.Navigation.openWebResource

启动Web资源时

在用Xrm.WebApi打开的Web资源的上下文中,有没有人尝试使用Xrm.Navigation.openWebResource?还是有人知道是否还需要其他步骤来检索数据?


更新

ENTITY_SET_NAMESmain.aspx中初始化。 我尝试将自定义Web资源直接嵌入到新的Main Form部分中,并且retrieveRecord方法有效。

仅当通过Xrm.Navigation.openWebResource从新页面运行Web资源时,这似乎才是问题。


更新2-对Aron的回复

我尝试按照以下建议使用window.parent

var contactId = "8553DA63-11C9-E711-A824-000D3AE0CB84";
var promise = parent.Xrm.WebApi.retrieveRecord("contact", contactId, "$select=contactid,firstname,lastname");`

并尽力尝试了window.parent.top

var contactId = "8553DA63-11C9-E711-A824-000D3AE0CB84";
var promise = parent.top.Xrm.WebApi.retrieveRecord("contact", contactId, "$select=contactid,firstname,lastname");`

但都导致了相同的错误

4 个答案:

答案 0 :(得分:3)

我的blog:)


为使此工作正常进行,我实施了 hacky 解决方法。

我一直在调试Xrm.WebApi方法,该方法在尝试获取实体名称并将其解析为 setname (复数)的行上失败。 。它通过比较传递给retrieveRecord方法的值并将其与全局变量ENTITY_SET_NAMES

进行比较
  

在我的示例中,它正在尝试将contact解析为contacts

很遗憾,此变量不存在,Xrm.WebApi引发错误

我的解决方法是检查此变量,如果不存在,请创建它! ENTITY_SET_NAMES是JSON可解析的字符串,其中包含每个实体的逻辑名和集名。

window["ENTITY_SET_NAMES"] = window["ENTITY_SET_NAMES"] || JSON.stringify({
  "account" : "accounts",
  "contact" : "contacts"
});

在对Xrm.WebApi方法的任何调用似乎都起作用之前执行此行,我现在得到结果

这是完整的代码段:

window["ENTITY_SET_NAMES"] = window["ENTITY_SET_NAMES"] || JSON.stringify({
  "account" : "accounts",
  "contact" : "contacts"
});

var contactId = "8553DA63-11C9-E711-A824-000D3AE0CB84";
Xrm.WebApi.retrieveRecord(
  "contact", 
  contactId, 
  "$select=contactid,firstname,lastname"
).then(
  function success(result) {
    console.log(result.firstname);
    // perform operations on record retrieval
  },
  function (error) {
    console.log(error.message);
    // handle error conditions
  }
);

答案 1 :(得分:3)

听起来像ClientGlobalContext.js.aspx中的产品错误,因为这应该为您提供整个工作环境。

在这种情况下,您可能可以使用window.opener.Xrm,因为it worked对应window.opener.Xrm.Page.getAttribute,它也应适用于Xrm.WebApi

您可以尝试从打开器窗口访问变量,如下所示:

window["ENTITY_SET_NAMES"] = window["ENTITY_SET_NAMES"] || window.opener.top.ENTITY_SET_NAMES;

答案 2 :(得分:2)

根据this article,当从Web资源引用主表单时,我们必须引用父窗口。虽然,它仅引用Xrm.Page和Xrm.Utility,它也应与Xrm.WebApi一起使用...

  

添加到表单的HTML Web资源不能使用由表单中加载的JavaScript库定义的全局对象。 HTML Web资源可以通过使用 parent.Xrm.Page 与表单中的 Xrm.Page Xrm.Utility 对象进行交互。 > parent.Xrm.Utility ,但无法使用父级访问由表单脚本定义的全局对象。

请尝试parent.Xrm.WebApi.retrieveRecord("contact", contactId, "$select=contactid,firstname,lastname");

This article还演示了parent.Xrm.WebApi

答案 3 :(得分:1)

如果您要使用绑定的动作和功能,还需要添加一个类似的变量,以将实体映射到其主ID字段。

window["ENTITY_PRIMARY_KEYS"] = ['{"account":"accountid", "contact":"contactid"}'];