Pre Validation Dataverse插件删除操作报错排查求助
Dataverse PreValidation删除插件报错排查与调试方案
问题描述
开发首个Dataverse插件时遇到删除操作无法完成的报错,导致无法调试。添加开关逻辑(bool on = !true; if (on == true){...})让插件不执行任何操作,客户端仍报错,该表现与InvalidPluginExecutionException类的预期行为一致。即使清空插件代码(仅保留命名空间和空类),删除操作依旧失败。
额外信息
- 实体:Dataverse表
phx_trainingtitles - 注册步骤:PreValidation - 同步
- 消息:Delete
- .NET Framework版本:4.6.2
完整代码
using System; using Microsoft.Xrm.Sdk; using Microsoft.Xrm.Sdk.Query; namespace Deleted_Metadata_Actions { public class PluginBasePreOp : IPlugin { public void Execute(IServiceProvider serviceProvider) { // Get the execution context and service provider IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId); // Create a "Switch" to turn Plugin on or off // Add or remove negation operator to change plugin state bool on = !true; if (on == true) { try { if (context.MessageName.ToLower() == "delete") { if (context.Stage == 10) // PreValidation (Synchronous) { if (context.PreEntityImages.Contains("PreEntityImage")) { Entity preImage = context.PreEntityImages["PreEntityImage"]; if (preImage.Contains("phx_jobtitle")) { string deletedJobTitle = preImage["phx_jobtitle"].ToString(); context.SharedVariables["DeletedJobTitle"] = deletedJobTitle; // Store in shared variable // Log the deletion event in PreValidation LogChangePreVal(service, context, deletedJobTitle); } else { throw new InvalidPluginExecutionException("Missing 'phx_jobtitle' in PreEntityImage."); } } else { throw new InvalidPluginExecutionException("PreEntityImage is missing."); } } else if (context.Stage == 40) // PostValidation (Asynchronous) { if (context.SharedVariables.Contains("DeletedJobTitle")) { string deletedJobTitle = context.SharedVariables["DeletedJobTitle"].ToString(); // Query to find related training users with the deleted job title QueryExpression query = new QueryExpression("phx_trainingusers") { ColumnSet = new ColumnSet("phx_traininguserid", "phx_jobtitles") // Retrieve details for logging }; query.Criteria.AddCondition("phx_jobtitles", ConditionOperator.Equal, deletedJobTitle); // Execute the query EntityCollection relatedUsers = service.RetrieveMultiple(query); // Log deletion event before actual deletion LogChangePostVal(service, context, deletedJobTitle); // Delete each related record foreach (var user in relatedUsers.Entities) { service.Delete("phx_trainingusers", user.Id); } } else { throw new InvalidPluginExecutionException("Shared variable 'DeletedJobTitle' is missing."); } } } } catch (Exception ex) { throw new InvalidPluginExecutionException($"An error occurred: {ex.Message}", ex); } } else { // On is false: Do nothing } } private void LogChangePreVal(IOrganizationService service, IPluginExecutionContext context, string deletedJobTitle) { Entity logEntry = new Entity("phx_changemanagement"); logEntry["phx_changetype"] = context.MessageName; // Message type (e.g., "Delete") logEntry["phx_initiatedby"] = new EntityReference("systemuser", context.UserId); // User who initiated deletion logEntry["phx_itemname"] = deletedJobTitle; // The job title being deleted service.Create(logEntry); // Save log entry } private void LogChangePostVal(IOrganizationService service, IPluginExecutionContext context, string deletedJobTitle) { Entity logEntry = new Entity("phx_changemanagement"); logEntry["phx_changetype"] = "Plugin_" + context.MessageName; // Plugin-specific logging logEntry["phx_initiatedby"] = nameof(PluginBasePreOp); // Plugin class name logEntry["phx_itemname"] = deletedJobTitle; // The deleted job title service.Create(logEntry); // Save log entry } } }
需求
想了解问题原因,以及如何在保留PreValidation注册的前提下让删除操作完成,以便进行调试。
内容的提问来源于stack exchange,提问作者SimpleMan
相关产品推荐
相关产品推荐

