XML数据必须先解析并映射为符合Dynamics 365实体逻辑名的JSON格式,再通过Web API(如ExecuteMultiple)导入;直接提交XML会导致415或400错误,Lookup和Option Set字段须按规范绑定GUID或整数值。

XML数据不能直接导入Dynamics 365,必须先转换为实体记录
Dynamics 365 的 Web API(包括 POST /api/data/v9.2/)不接受原始 XML 作为请求体。它只支持 JSON 格式创建、更新或批量操作。如果你手头只有 XML,第一步不是调 API,而是解析并映射成符合目标实体结构的 JSON 对象。
常见错误现象:415 Unsupported Media Type 或 400 Bad Request,因为直接把 XML 当作 Content-Type: application/json 发送,服务端根本无法解析。
- XML 必须用你熟悉的语言(如 Python、C#、PowerShell)解析(例如用
xml.etree.ElementTree或XDocument) - 每个 XML 节点需对应到 D365 实体字段名(注意大小写和逻辑名,比如
account实体的主键字段是accountid,不是id) - 查找字段逻辑名最可靠的方式:进入 D365 管理界面 → 进入对应实体 → “字段” → 查看“逻辑名称”列
使用 Web API 创建单条记录时,JSON 字段名必须用逻辑名而非显示名
很多人从 UI 上看到字段叫“客户名称”,就误用 "Customer Name": "ABC Corp",结果返回 400 Bad Request 并提示 Unknown property 'Customer Name' on type 'Microsoft.Dynamics.CRM.account'。
正确做法是查该字段的逻辑名(通常是小写+下划线或驼峰),例如:
{
"name": "ABC Corp",
"telephone1": "555-0123",
"address1_city": "Seattle"
}关键点:
-
name是account实体的主字段逻辑名,不是Account Name - 自定义字段逻辑名类似
new_customernumber,前缀取决于解决方案命名空间 - 查找逻辑名不要依赖导出的 Excel 模板(它用的是显示名),而要查系统元数据或使用
GET /api/data/v9.2/EntityDefinitions(LogicalName='account')/Attributes
批量导入大量 XML 记录?优先用 ExecuteMultiple + JSON 数组,别手写循环
如果 XML 包含上百条记录,逐条 POST 会触发限流(默认每分钟 6000 次请求,但单用户实际阈值更低),且网络开销大。应改用 ExecuteMultiple 操作,一次提交最多 1000 条请求。
实操建议:
- 将 XML 解析后的每条数据转为一个
CreateRequest对象(C#)或构造等效的 JSON 请求体数组(其他语言) - 请求 URL:
POST /api/data/v9.2/ExecuteMultiple - 请求体必须是
ExecuteMultipleRequest结构,其中Requests是包含多个CreateRequest的数组 - 注意设置
ContinueOnError = true和ReturnResponses = true,便于定位哪条 XML 记录失败
Python 示例(简化版,使用 requests):
import requests
import json
<p>url = "<a href="https://www.php.cn/link/32075cd98185a51c9d1b2733971a1713">https://www.php.cn/link/32075cd98185a51c9d1b2733971a1713</a>"
headers = {
"Authorization": "Bearer YOUR_ACCESS_TOKEN",
"Content-Type": "application/json",
"OData-MaxVersion": "4.0",
"OData-Version": "4.0"
}</p><h1>假设 xml_to_json_list() 已将 XML 解析为 3 条 account 记录的 JSON dict 列表</h1><p>requests_payload = [
{"@odata.type": "Microsoft.Dynamics.CRM.account", "name": "Client A"},
{"@odata.type": "Microsoft.Dynamics.CRM.account", "name": "Client B"},
{"@odata.type": "Microsoft.Dynamics.CRM.account", "name": "Client C"}
]</p><p>payload = {
"Requests": [
{"@odata.type": "Microsoft.Dynamics.CRM.CreateRequest", "Target": item}
for item in requests_payload
],
"ContinueOnError": True,
"ReturnResponses": True
}</p><p>response = requests.post(url, headers=headers, data=json.dumps(payload))</p>关联字段(Lookup)和选项集(Option Set)最容易填错
XML 里可能存的是“销售经理:张三”,但 D365 Lookup 字段(如 primarycontactid)必须传 GUID,且要指向 contact 实体;选项集字段(如 industrycode)必须传整数,不是文本。
典型错误:
- 把
<Industry>Manufacturing</Industry>直接映射为"industrycode": "Manufacturing"→ 报错Invalid value for option set - 把联系人姓名当 ID 用:
"primarycontactid": "张三"→ 报错Invalid lookup value
解决办法:
- 选项集值需提前查:用
GET /api/data/v9.2/EntityDefinitions(LogicalName='account')/Attributes(LogicalName='industrycode')/OptionSet - Lookup 字段必须先通过查询(如
GET /api/data/v9.2/contacts?$filter=fullname eq '张三')获取目标记录的contactid,再填入"primarycontactid@odata.bind": "/contacts(00000000-0000-0000-0000-000000000000)" - 注意
@odata.bind语法不能省略,也不能写成@odata.id或纯 GUID
XML 数据本身只是载体,Dynamics 365 关心的是实体关系、类型约束和安全上下文。跳过字段逻辑名验证、忽略 Lookup 绑定语法、或试图绕过 JSON 转换——这些都会让导入卡在第一关。









