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

模型驱动应用中阻止用户自选的XRM脚本失效问题排查

模型驱动应用中阻止Lookup字段选择自身的脚本失效问题排查与修复

问题概述

开发了客户端脚本,意图阻止用户在关联AAD User表的Lookup字段(digphil_peerreviewer)中选择自身,但脚本未生效,用户仍可选择自己。原代码如下:

function preventSelfSelection(executionContext) {
  var formContext = executionContext.getFormContext();
  // Retrieve the current user ID without curly braces
  var userId = Xrm.Utility.getGlobalContext().userSettings.userId.replace("{", "").replace("}", "");
  console.log("Current User ID: ", userId);

  // Retrieve AAD ObjectId of the current user via Web API
  Xrm.WebApi.retrieveRecord("systemuser", userId, "?$select=azureactivedirectoryobjectid").then(
    function success(result) {
      var currentAADObjectId = result.azureactivedirectoryobjectid;
      console.log("Current User AAD ObjectId: ", currentAADObjectId);

      // Get the AAD ObjectId from the "digphil_peerreviewer" field
      var peerreviewer = formContext.getAttribute("digphil_peerreviewer").getValue();
      if (peerreviewer && peerreviewer.length > 0) {
        // Retrieve the selected user ID without curly braces
        var selectedUserId = peerreviewer[0].id.replace("{", "").replace("}", "");
        console.log("Selected User ID: ", selectedUserId);

        // Get AAD ObjectId of the selected user
        Xrm.WebApi.retrieveRecord("systemuser", selectedUserId, "?$select=azureactivedirectoryobjectid").then(
          function success(peerreviewerResult) {
            var selectedAADObjectId = peerreviewerResult.azureactivedirectoryobjectid;
            console.log("Selected User AAD ObjectId: ", selectedAADObjectId);

            if (currentAADObjectId.toLowerCase() === selectedAADObjectId.toLowerCase()) {
              formContext.getControl("digphil_peerreviewer").setNotification("You cannot select yourself", "self_selection_error");
              formContext.getAttribute("digphil_peerreviewer").setValue(null);
              console.log("User attempted to select themselves. Resetting field.");
            } else {
              formContext.getControl("digphil_peerreviewer").clearNotification("self_selection_error");
            }
          },
          function(error) {
            console.log("Error fetching selected user AAD ObjectId: ", error.message);
            // Handle error
          }
        );
      }
    },
    function(error) {
      console.log("Error fetching current user AAD ObjectId: ", error.message);
      // Handle error
    }
  );
};

问题原因分析

  1. 事件绑定错误:脚本大概率只绑定了表单OnLoad事件,未绑定digphil_peerreviewer字段的OnChange事件。Lookup字段值变化时不会触发OnLoad,导致校验逻辑完全不执行。
  2. 冗余异步请求导致延迟:原代码通过两次Xrm.WebApi.retrieveRecord获取AAD ObjectId做对比完全没必要——Lookup字段关联的是systemuser表,选中值的id就是当前环境的系统用户ID,直接对比即可。异步请求会导致校验不及时,甚至用户已经保存记录后才触发字段重置。
  3. 未处理字段清空场景:当用户清空digphil_peerreviewer字段时,原代码不会清除已有的通知,导致提示残留。

修复后的代码

function preventSelfSelection(executionContext) {
    try {
        var formContext = executionContext.getFormContext();
        if (!formContext) return;

        // 获取当前用户ID(保留大括号,与Lookup返回的ID格式一致)
        var currentUserId = Xrm.Utility.getGlobalContext().userSettings.userId;
        var peerReviewerAttr = formContext.getAttribute("digphil_peerreviewer");
        var peerReviewerCtrl = formContext.getControl("digphil_peerreviewer");

        // 先清除之前的通知,避免残留
        peerReviewerCtrl.clearNotification("self_selection_error");

        var selectedUser = peerReviewerAttr.getValue();
        if (selectedUser && selectedUser.length > 0) {
            var selectedUserId = selectedUser[0].id;
            // 直接对比系统用户ID,无需绕路查AAD ObjectId
            if (selectedUserId.toLowerCase() === currentUserId.toLowerCase()) {
                peerReviewerCtrl.setNotification("不能选择自己", "self_selection_error");
                peerReviewerAttr.setValue(null);
                console.log("用户尝试选择自己,已重置字段");
            }
        }
    } catch (error) {
        console.log("校验逻辑执行出错:", error.message);
    }
}

关键修复点说明

  • 绑定正确事件:将脚本绑定到digphil_peerreviewer字段的OnChange事件,确保字段值变化时立即触发校验。
  • 移除冗余异步请求:直接对比当前用户ID与Lookup选中的用户ID,避免异步延迟,提升响应速度。
  • 完善异常处理:增加try-catch捕获执行错误,避免脚本崩溃影响其他表单逻辑。
  • 处理字段清空场景:每次执行校验前先清除通知,避免提示残留。

额外优化建议

  • 视图层面过滤:如果业务允许,可以修改digphil_peerreviewer字段对应的Lookup视图,添加过滤条件systemuserid ne {当前用户ID},从源头阻止用户看到自己,减少前端校验的必要性。
  • 统一ID格式:保留ID的大括号格式直接对比,避免字符串替换可能出现的格式错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 16:15:10