如何从关联视图的RibbonWorkbench以支持方式获取Dynamics 365 FormContext?
官方支持的Dynamics 365关联视图Ribbon按钮获取主记录ID和名称方案
场景回顾
- 环境:Dynamics v9本地部署,需兼容Dynamics 365 Online
- 操作:Account表单子网格的关联视图中,点击Ribbon按钮触发JavaScript函数,已传入
primaryControl参数 - 目标:获取当前Account的ID和名称
现有代码分析
你当前通过primaryControl.get_crmFormControl().getFormContext()的方式能正常获取数据,但get_crmFormControl()属于非官方公开API,微软未在官方文档中披露该方法,随时可能修改或移除,无法保证在Dynamics 365 Online的长期兼容性,不建议用于生产环境。
官方支持的实现方案
方法1:通过Ribbon命令参数直接传递主记录信息
这是最稳定的官方方案,无需依赖primaryControl的内部逻辑:
- 打开Ribbon配置工具(如Ribbon Workbench),找到目标按钮对应的命令
- 在命令的参数配置中添加两个参数:
- 参数1:类型选择
PrimaryEntityId,用于传递主记录ID - 参数2:类型选择
PrimaryEntityAttribute,用于传递主记录的名称(即Account的主属性值)
- 参数1:类型选择
- 修改JavaScript函数直接接收这两个参数:
function myFunction(accountId, accountName) { // 自动去除ID的大括号(部分版本已处理,可按需验证) accountId = accountId.replace(/[{}]/g, ""); console.log("Account ID:", accountId); console.log("Account Name:", accountName); }
方法2:通过官方兼容逻辑获取表单上下文
针对Mscrm.FormProxyForRibbon类型的primaryControl,可通过官方公开的兼容判断获取表单上下文:
function myFunction(primaryControl) { let formContext; // 优先使用官方公开的API if (primaryControl.getFormContext) { formContext = primaryControl.getFormContext(); } else if (primaryControl.formContext) { formContext = primaryControl.formContext; } // 降级兼容非公开方法(仅作为兜底) else if (primaryControl.get_crmFormControl) { formContext = primaryControl.get_crmFormControl().getFormContext(); } if (formContext) { const accountId = formContext.data.entity.getId().replace(/[{}]/g, ""); const accountName = formContext.data.entity.getPrimaryAttributeValue(); console.log("Account ID:", accountId); console.log("Account Name:", accountName); } else { console.error("无法获取表单上下文"); } }
兼容性说明
- 上述两种方案均支持Dynamics v9本地部署及所有后续Dynamics 365 Online版本
- 优先选择方法1,参数传递的方式不依赖表单上下文的内部实现,稳定性最高
内容的提问来源于stack exchange,提问作者cmartin
相关产品推荐
相关产品推荐

