You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Dynamics 365 CE WebAPI如何仅更新用户修改的字段?

解决Dynamics 365 CE Web API Patch请求的字段更新问题

嘿,我来帮你梳理下针对这个场景的可行方案,先纠正一个关键误区:Dynamics 365的Web API Patch请求本身就是只更新你在请求体里提交的字段,不需要发送整条记录。你困惑的点其实是「如何在没有可靠客户端变更追踪的情况下,只提交修改过的字段」对吧?下面是几个实用的解决思路:

1. 实现轻量级客户端字段对比(推荐)

虽然是Web应用,但做简单的字段快照对比其实没那么复杂,步骤大概是这样:

  • 加载记录时,把原始字段值存在内存里(比如一个JS对象)
  • 用户修改表单后,获取当前的表单字段值
  • 对比原始对象和当前对象,筛选出值发生变化的字段
  • 只把这些变化的字段打包成JSON,发送Patch请求

举个简单的JavaScript示例:

// 加载CRM记录时保存原始数据
const originalAccount = await fetch("/api/data/v9.1/accounts(12345)")
  .then(res => res.json());

// 用户修改后,获取表单当前数据
const currentAccount = {
  name: document.getElementById("accountName").value,
  emailaddress1: document.getElementById("accountEmail").value,
  telephone1: document.getElementById("accountPhone").value
};

// 找出差异字段(注意:复杂类型如lookup、选项集需特殊对比,这里简化处理)
const changedFields = {};
Object.keys(currentAccount).forEach(field => {
  if (originalAccount[field] !== currentAccount[field]) {
    changedFields[field] = currentAccount[field];
  }
});

// 只发送变更字段做Patch
if (Object.keys(changedFields).length > 0) {
  await fetch(`/api/data/v9.1/accounts(12345)`, {
    method: "PATCH",
    headers: {
      "Content-Type": "application/json",
      // 推荐加上ETag做并发控制,避免覆盖他人修改
      "If-Match": originalAccount["@odata.etag"]
    },
    body: JSON.stringify(changedFields)
  });
}

这种方式代码量不大,却能保证请求的高效性,不会冗余更新未修改的字段。

2. 退而求其次:发送整条记录的Patch请求

如果实在不想做客户端对比,直接发送整条记录的Patch请求也是可行的,但有个小细节:

  • 如果你提交的字段值和CRM服务器上的当前值完全一致,Dynamics不会实际更新该业务字段,只会更新modifiedonmodifiedby这类系统字段
  • 这种方式的代价是会产生不必要的系统字段更新,以及请求体略大,但胜在实现简单

3. 配合ETag做并发控制(必加优化)

不管你选择哪种方式,都强烈建议在Patch请求里带上ETag(即记录的@odata.etag值),通过If-Match请求头传递。这样如果用户加载记录后,该记录被其他用户修改过,Web API会返回412 Precondition Failed状态码,提醒你重新加载最新数据,避免数据覆盖冲突。

关键补充

Dynamics 365 Web API确实没有内置的「自动对比服务器记录并只更新差异」的功能——因为RESTful API的设计原则是客户端明确告知服务器要修改哪些字段。所以最合理的方案还是实现轻量级的客户端字段对比,既高效又符合API的设计语义。

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

火山引擎 最新活动