9

我使用以下方法在新窗口中打开了一个 HTML Web 资源:

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

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

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


更新

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

看来这只有在通过新页面运行 Web 资源时才会出现问题Xrm.Navigation.openWebResource


更新 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

4 回答 4

4

听起来像是 中的产品错误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;
于 2018-07-25T18:45:56.760 回答
3

我的博客:)


为了让这个工作,我实施了一个hacky解决方法。

我一直在调试Xrm.WebApi方法,它在尝试获取实体名称并将其解析为集合名称(复数)的行上失败了。它通过比较传递给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
  }
);
于 2018-07-20T02:05:24.327 回答
2

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

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

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

这篇文章还演示了parent.Xrm.WebApi

于 2018-07-19T11:07:52.403 回答
2

如果您要使用绑定的操作和函数,您还需要添加一个类似的变量来将实体映射到它们的主要 id 字段。

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

于 2018-11-12T04:30:05.980 回答