SimpleMan
SimpleMan

Reputation: 13

Pre Validation Dataverse Plugin - Error on delete

I'm developing my first dataverse plugin. My issue is I get an error preventing the delete action from completing. Thus, I can't debug. Assuming there was an issue with the code, I added a "Switch" to turn the execution on or off for testing.

bool on = !true;
if (on == true)
{...

This should have effectively caused the plugin to do nothing. However, I still get an error on the client side. This behavior is aligned with the expected behavior of the InvalidPluginExecutionException Class. The docs (https://learn.microsoft.com/en-us/dotnet/api/microsoft.xrm.sdk.invalidpluginexecutionexception?view=dataverse-sdk-latest) state: "When thrown by a plug-in, the Microsoft Dataverse platform displays to the user the exception message in a dialog of the Web application.". Which is exactly what's happening.
So, I remove All the code from the plugin as such and

using System;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;

namespace Deleted_Metadata_Actions
{
    public class PluginBasePreOp
    {
    }
}

Same behavior. Error when deleting and unable to delete the item. See error below.
Dataverse error

So, what's going on?
I feel like I'm missing something simple. I need the delete action to complete so I can have a profile to debug. How can I have the plugin registered on pre validation and get the delete action to complete?

Additional details.

Entity: dataverse table 'phx_trainingtitles'
Registered step: PreValidation - Synchronous
Message: Delete
.NET Framework - 4.6.2

Plugin Registration Tool

Full code:

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
        }
    }
}

Upvotes: 0

Views: 17

Answers (0)

Related Questions