You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JavaScript在Dynamics 365 CRM(UCI)中取消保存操作?

Dynamics 365 CRM OnSave事件取消问题解决方案

问题分析

  1. 空函数触发UciError: Cannot save due to no dirty changes.
    • 这是CRM默认行为:用户尝试保存无任何字段变更的记录时,系统会抛出该错误。即使事件处理程序的「启用」复选框未勾选仍出现,大概率是浏览器缓存或后台事件注册未同步导致,实际事件仍被触发。
  2. 调用preventDefault()后触发UciError: Cannot save due to PreventDefault encountered.
    • 该错误是预期结果:preventDefault()会直接阻止表单保存操作,系统会抛出此提示告知保存被中断。但我们需要结合业务逻辑(如WebApi查重结果)来控制是否阻止,而非无条件调用。

解决方案

1. 解决空函数时的无变更保存报错

在函数开头增加表单脏状态判断,无变更时直接返回,不执行后续逻辑:

checkForDuplicate = function (executionContext) {
    const formContext = executionContext.getFormContext();
    // 无字段变更时直接返回,避免系统报错
    if (!formContext.data.entity.getIsDirty()) {
        return;
    }
    // 后续逻辑...
}

同时检查事件注册的实际状态:进入CRM解决方案,找到对应实体的事件注册记录,确认是否真的禁用了该事件处理程序,避免UI显示与后台不同步。

2. 结合WebApi异步逻辑控制OnSave事件

由于WebApi请求是异步操作,需先阻止默认保存,待请求返回后再决定是否执行保存或提示用户:

  • 事件注册时必须勾选「启用异步处理」选项
  • 示例代码:
checkForDuplicate = async function (executionContext) {
    const formContext = executionContext.getFormContext();
    const args = executionContext.getEventArgs();

    // 无变更时直接返回
    if (!formContext.data.entity.getIsDirty()) {
        return;
    }

    // 先阻止默认保存,等待异步查重结果
    args.preventDefault();

    try {
        // 获取要查重的字段值(以区域名称为例)
        const territoryName = formContext.getAttribute("name").getValue();
        if (!territoryName) {
            // 名称为空时允许保存
            formContext.data.entity.save();
            return;
        }

        // 调用WebApi查询是否存在同名活跃区域
        const query = `?$select=name&$filter=name eq '${encodeURIComponent(territoryName)}' and statecode eq 0`;
        const response = await Xrm.WebApi.retrieveMultipleRecords("territory", query);

        if (response.entities.length > 0) {
            // 存在重复,提示用户不保存
            Xrm.Navigation.openAlertDialog({ text: "该区域名称已存在,无法保存。" });
        } else {
            // 无重复,执行保存
            formContext.data.entity.save();
        }
    } catch (error) {
        console.error("查重失败:", error);
        Xrm.Navigation.openAlertDialog({ text: "检查重复时出错,请稍后重试。" });
        // 可选:出错时允许保存,注释掉则不保存
        // formContext.data.entity.save();
    }
}

关键说明

  • 异步函数必须搭配事件注册的「启用异步处理」,否则会导致表单无响应或报错。
  • 避免无条件调用preventDefault(),仅在需要基于异步结果控制保存时才先阻止,后续根据业务逻辑决定是否触发保存。

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 02:54:36