Dynamics中更新Contact Preferred Contact Method字段异常问题排查
Dynamics 联系人插件异常问题排查与修复
你的插件每次更新联系人都会抛出异常,核心问题有两个:
- 空引用异常触发:你直接访问
entity.GetAttributeValue<OptionSetValue>("preferredcontactmethodcode").Value,但如果用户更新时没修改Preferred Contact Method字段,Target实体里不会包含这个属性,GetAttributeValue会返回null,此时访问Value就会直接抛出空引用异常。 - 字段值判断逻辑错误:你只检查Target里的
emailaddress1和telephone1,但如果这些字段是之前已经填好的(本次更新没改动),Target里不会包含它们,代码会误判为空,导致符合条件时也抛异常。
修复方案
需要通过PreImage获取联系人的原有字段值,同时增加空引用检查,确保逻辑只在确实不符合规则时触发异常。步骤如下:
- 插件注册时配置PreImage:注册插件时,添加一个PreImage,命名为
PreContactImage,并勾选preferredcontactmethodcode、emailaddress1、telephone1三个字段。 - 修改代码逻辑:优先使用Target中的更新值,没有则从PreImage取原有值,同时增加空值判断。
修复后的代码:
using System; using Microsoft.Xrm.Sdk; namespace BasicPluginTwo { public class ContactUpdatePlugin : IPlugin { public void Execute(IServiceProvider serviceProvider) { ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService)); IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity targetEntity) { if (targetEntity.LogicalName != "contact") return; // 获取PreImage中的原有实体数据 Entity preImage = context.PreEntityImages.Contains("PreContactImage") ? context.PreEntityImages["PreContactImage"] : null; // 获取Preferred Contact Method的值:优先取Target的更新值,没有则取PreImage的原有值 OptionSetValue preferredContactMethodOptionSet = targetEntity.Contains("preferredcontactmethodcode") ? targetEntity.GetAttributeValue<OptionSetValue>("preferredcontactmethodcode") : preImage?.GetAttributeValue<OptionSetValue>("preferredcontactmethodcode"); // 如果没有获取到选项值,直接返回(比如新建联系人且未设置该字段时) if (preferredContactMethodOptionSet == null) return; int preferredContactMethodOption = preferredContactMethodOptionSet.Value; // 获取邮箱地址:优先取Target的更新值,没有则取PreImage的原有值 string email = targetEntity.Contains("emailaddress1") ? targetEntity.GetAttributeValue<string>("emailaddress1") : preImage?.GetAttributeValue<string>("emailaddress1") ?? string.Empty; // 获取电话:优先取Target的更新值,没有则取PreImage的原有值 string phone = targetEntity.Contains("telephone1") ? targetEntity.GetAttributeValue<string>("telephone1") : preImage?.GetAttributeValue<string>("telephone1") ?? string.Empty; // 仅在选定对应联系方式但未填写对应字段时抛出异常 if ((preferredContactMethodOption == 2 && string.IsNullOrEmpty(email)) || (preferredContactMethodOption == 3 && string.IsNullOrEmpty(phone))) { throw new InvalidPluginExecutionException("Preferred Contact Method requires a corresponding non-empty contact detail."); } } } } }
关键改动说明
- 增加PreImage的读取逻辑,确保能获取到联系人的原有字段值
- 对
preferredcontactmethodcode增加空值判断,避免空引用异常 - 邮箱和电话的取值逻辑改为优先用更新值,无更新则用原有值,避免误判为空
- 只有当确实选中了邮件/电话联系方式但对应字段为空时,才抛出异常
内容的提问来源于stack exchange,提问作者FluctLigth
相关产品推荐
相关产品推荐

