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



>我在一个新窗口中打开了一个HTML网络资源:

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

这是一个 HTML Web 资源,它正在头部加载客户端对象

<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对象为空,因此发生错误(空引用)

我尝试将我的 Web 资源嵌入到 CRM 页面中,并且代码工作正常。问题似乎是当通过Xrm.Navigation.openWebResource启动 Web 资源时

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


更新

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");`

但两者都导致了相同的错误

听起来像是ClientGlobalContext.js.aspx中的产品错误,因为这应该为您提供完整的上下文。

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

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

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

我的博客:)


为了使它工作,我实施了一个黑客变通方法。

我一直在调试 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
}
);

根据本文,当从 Web 资源引用主窗体时,我们必须引用父窗口。虽然,它只引用 Xrm.Page 和Xrm.Utility,但它也应该与Xrm.WebApi一起工作。

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

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

本文还演示了parent.Xrm.WebApi

如果要使用绑定操作和函数,则还需要添加类似的变量以将实体映射到其主 id 字段。

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

尝试使用开瓶器。Xrm 访问从父级中描述的表单打开的独立 Web 资源中的 Xrm 对象。Xrm 部分:https://learn.microsoft.com/en-us/power-platform/important-changes-coming#some-client-apis-are-deprecated

"如果getContentWindow方法不起作用,您可以使用parent。Xrm 以访问 HTML Web 资源中的 Xrm 对象。如果在新窗口中打开 HTML Web 资源,则应使用打开器。而是Xrm。

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

最新更新