Microsoft Dynamics CRM:从表单取值时遭遇ISV代码异常问题
解决Dynamics CRM插件中"An unexpected error occurred from ISV code"报错问题
尝试从Microsoft Dynamics CRM表单获取值并通过Windows窗体打印,保存时失败,报错**"An unexpected error occurred from ISV code"**,相关C#代码如下:
public void Execute(IServiceProvider serviceProvider) { // Get the context and organization service IPluginExecutionContext context = (IPluginExecutionContext) serviceProvider.GetService(typeof (IPluginExecutionContext)); IOrganizationServiceFactory factory = (IOrganizationServiceFactory) serviceProvider.GetService(typeof (IOrganizationServiceFactory)); IOrganizationService service = factory.CreateOrganizationService(context.UserId); Entity target = context.InputParameters["Target"] as Entity; try { EntityReference lookupValue = target.GetAttributeValue<EntityReference>("new_contact"); EntityReference lookupValue2 = target.GetAttributeValue<EntityReference>("new_account"); // string contactname = target.GetAttributeValue<string>("new_contact"); // string accountname = target.GetAttributeValue<string>("new_account"); MessageBox.Show("" + lookupValue + " " + lookupValue2); } catch (Exception ex) { throw new InvalidPluginExecutionException(ex.Message); } }
报错原因
- 服务器端插件禁止客户端UI操作:Dynamics CRM的插件运行在服务器环境中,没有桌面交互能力,调用
MessageBox.Show这类客户端UI组件API会直接触发异常,这就是报错的根源。 - EntityReference处理错误:直接将
EntityReference对象拼接为字符串,会输出对象类型名而非实际的关联记录名称,无法得到有效数据。
修正方案
替换客户端UI操作,改用CRM插件允许的方式反馈数据或记录日志,同时正确处理EntityReference字段值:
public void Execute(IServiceProvider serviceProvider) { // 获取上下文、组织服务和跟踪日志服务 IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = factory.CreateOrganizationService(context.UserId); ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService)); Entity target = context.InputParameters["Target"] as Entity; try { EntityReference lookupValue = target.GetAttributeValue<EntityReference>("new_contact"); EntityReference lookupValue2 = target.GetAttributeValue<EntityReference>("new_account"); // 安全获取关联记录的名称(避免空引用) string contactName = lookupValue?.Name ?? "未关联联系人"; string accountName = lookupValue2?.Name ?? "未关联账户"; // 选项1:给前端用户弹出提示(仅适用于同步插件) throw new InvalidPluginExecutionException($"关联信息:联系人[{contactName}],账户[{accountName}]"); // 选项2:写入插件跟踪日志(推荐用于调试,不影响用户操作) // tracingService.Trace("关联联系人:{0},关联账户:{1}", contactName, accountName); } catch (Exception ex) { // 记录错误日志并抛出友好提示 tracingService.Trace("插件执行异常:{0}", ex.ToString()); throw new InvalidPluginExecutionException("数据处理失败,请联系管理员。"); } }
注意事项
- 插件运行在服务器端,绝对禁止使用任何客户端UI交互API(如
MessageBox、Windows Form等)。 - 如果需要给前端用户反馈,使用
InvalidPluginExecutionException抛出消息,CRM前端会自动弹出提示框。 - 调试插件时,优先使用
ITracingService写入跟踪日志,可在CRM系统的「插件跟踪日志」中查看详细执行信息。 - 确认
new_contact和new_account是查找字段(EntityReference类型),且在插件触发的消息(如Create/Update)中,该字段已被包含在Target参数内(Update消息需确保字段被修改或注册插件时勾选「传递所有属性」)。
内容的提问来源于stack exchange,提问作者Muhammad Usman Khan
相关产品推荐
相关产品推荐

