使用CrmSdk.CoreAssemblies v9对接Dynamics CRM 2013:ConcurrencyBehavior序列化问题
解决方案与兼容说明
问题根源
升级后的高版本CrmSdk(针对Dynamics 365)会默认使用新版本的服务契约元素(如ConcurrencyBehavior枚举),而CRM 2013对应的SDK 6.x体系中不存在这些类型,导致与CRM2013通信时出现反序列化失败。
可行解决方案
1. 分环境适配不同SDK版本
这是最稳妥的方案:
- 将代码核心逻辑抽象为通用接口(如
ICrmDataHandler),分别实现针对CRM2013(依赖Sdk 6.1.2)和Dynamics 365(依赖高版本Sdk)的具体实现类。 - 通过项目条件编译、多目标框架或者依赖注入动态切换实现,从根源避免版本冲突。
2. 自定义DataContractResolver修复反序列化
根据错误提示,通过自定义解析器处理高版本类型映射:
- 实现
DataContractResolver,当遇到CRM高版本命名空间下的未知类型(如http://schemas.microsoft.com/xrm/7.1/Contracts:ConcurrencyBehavior),将其映射到兼容类型(如int)或直接忽略。 - 示例代码:
public class CrmCrossVersionResolver : DataContractResolver { public override Type ResolveName(string typeName, string typeNamespace, Type declaredType, DataContractResolver knownTypeResolver) { // 处理ConcurrencyBehavior的兼容映射 if (typeNamespace == "http://schemas.microsoft.com/xrm/7.1/Contracts" && typeName == "ConcurrencyBehavior") { return typeof(int); // 用int替代未知枚举类型 } // 其他类型交给默认解析器 return knownTypeResolver.ResolveName(typeName, typeNamespace, declaredType, knownTypeResolver); } public override bool TryResolveType(Type type, Type declaredType, DataContractResolver knownTypeResolver, out XmlDictionaryString typeName, out XmlDictionaryString typeNamespace) { return knownTypeResolver.TryResolveType(type, declaredType, knownTypeResolver, out typeName, out typeNamespace); } }
- 将自定义解析器注入到
OrganizationServiceProxy的序列化配置中:
var serviceProxy = new OrganizationServiceProxy(uri, homeRealmUri, credentials, deviceCredentials); foreach (var operation in serviceProxy.Endpoint.Contract.Operations) { var behavior = operation.Behaviors.Find<DataContractSerializerOperationBehavior>(); if (behavior != null) { behavior.DataContractResolver = new CrmCrossVersionResolver(); } }
3. 禁用高版本SDK的自动新特性
高版本SDK可能会自动添加新请求参数,手动控制请求行为:
- 在调用
SaveChanges时,明确使用CRM2013兼容的SaveChangesOptions,避免触发高版本特性。 - 检查
OrganizationServiceContext的配置,关闭可能引入新类型的自动处理逻辑。
关于跨版本兼容SDK的说明
不存在同时完全兼容CRM2013和Dynamics 365的单一CrmSdk版本:
- 微软官方的向后兼容支持仅覆盖到CRM 2016及以后版本,CRM2013发布时间过早,高版本SDK中大量新增的类型、契约无法被CRM2013识别。
- 强行使用高版本SDK对接CRM2013,即使通过解析器修复部分问题,仍可能存在其他隐藏的兼容性风险(如API调用格式差异)。
内容的提问来源于stack exchange,提问作者K. Oja
相关产品推荐
相关产品推荐

