.NET Core 3.1中ServiceClient连接Dynamics出现重复代理类型错误
.NET Core 3.1函数应用连接Dynamics重复代理类型错误的分析与解决
问题背景
.NET Core 3.1 Azure函数应用通过ServiceClient连接Dynamics 365时,非随机出现连接失败,错误提示为Failed to lookup current organization data,底层原因是代理类型(如msdyncrm_GetReactions)被重复定义。问题仅在FunctionStartup初始化作用域生命周期的仓储类时触发,且存在以下特征:
- 改用latebound并移除earlybound文件后问题消失,但其他同架构的earlybound+ServiceClient应用正常运行
- 仅SIT环境出现该问题,DEV环境无异常
- 删除当前报错类型后,会有其他类型报相同的重复定义错误
- 本地运行正常,仅部署到Azure函数应用后触发
- 重启函数应用可临时恢复服务
可能的根因
- Azure函数沙箱的程序集加载机制:Azure函数的沙箱环境中,应用重启、缩放或预热过程中,可能出现earlybound实体程序集被多次加载到不同应用域的情况,导致类型重复定义。
- SIT环境Dynamics元数据异常:SIT环境的Dynamics实例可能存在重复的自定义操作/实体元数据,或者元数据缓存失效,导致
ServiceClient生成代理时重复创建类型。 - DI初始化并发冲突:
FunctionStartup中初始化作用域服务时,若并发触发ServiceClient的元数据加载逻辑,会导致代理类型被重复生成。 - earlybound代码生成问题:基于DEV环境元数据生成的earlybound代码,与SIT环境的元数据存在冲突,或者生成过程中出现重复类型定义。
解决建议
优化earlybound代码生成
- 针对SIT环境的Dynamics元数据重新生成earlybound代码,禁止直接复用DEV环境生成的代码
- 使用
CrmSvcUtil生成代码时,添加/excludeTypes参数临时排除重复报错的类型;同时登录SIT环境Dynamics后台,检查是否存在重复的自定义操作(如msdyncrm_GetReactions)并删除 - 为earlybound代码指定独立的命名空间,避免与系统类型或其他业务程序集的类型冲突
调整ServiceClient初始化逻辑
- 不在
FunctionStartup中直接初始化ServiceClient,改为在作用域仓储类内部延迟初始化,确保每个作用域仅初始化一次 - 对
ServiceClient的元数据加载逻辑添加锁机制,防止并发场景下重复生成代理类型 - 开启
ServiceClient的代理缓存:设置EnableProxyTypesCache = true,减少重复生成代理的次数
调整Azure函数应用配置
- 检查SIT环境函数应用是否启用了预热实例,若启用可尝试关闭,避免预热过程中程序集重复加载
- 调整函数应用的缩放模式,避免快速自动缩放导致多个实例同时初始化时出现元数据加载冲突
- 将earlybound实体类打包为独立的类库程序集,与函数应用主程序集分离部署,降低重复加载概率
排查Dynamics SIT环境元数据
- 登录SIT环境Dynamics,检查自定义操作、实体的元数据,确认是否存在重复定义的项(如
msdyncrm_GetReactions操作是否被多次创建),清理重复元数据 - 刷新Dynamics的元数据缓存,确保
ServiceClient获取的是最新且唯一的元数据
临时应急方案
若上述方案无法快速落地,可临时改用latebound方式操作Dynamics,待根源问题排查解决后再切换回earlybound模式
内容的提问来源于stack exchange,提问作者CNAP
相关产品推荐
相关产品推荐

