In one of our plugins, we encountered “The specified domain does not exist or cannot be contacted – System.FormatException: Input string was not in a correct format” error. Basically this issue can arise due to incorrect string formatting, unexpected data types, or missing values.
Our initial thought was that it could be because one of the GUID data type fields was null and being used in the Retrieve method.
However, it turned out to be because of the following trace statement.
Sample code –
Extra space inside { 1}. The correct syntax is {1} instead of { 1}. We removed the extra space.
In Microsoft Dataverse, calculated columns are a powerful way to derive values dynamically without the need for manual updates. However, one challenge is that plugins do not trigger directly on calculated column changes since these values are computed at runtime and not stored in the database.
Since calculated columns use/depend on other fields, we can register a plugin on the change of those dependent fields. If a calculated column Total Amount is based on Quantity and Unit Price, then we can trigger the plugin on the Update event of Quantity and Unit Price.
Let us see it in action, we have the below plugin registered in the update event.
On specifying the Formula / Calculated column as a Filtering attribute, our plugin doesn’t get triggered.
Here we updated the Unit Price, which changed the Total Amount, but we do not see any trace log generated.
Now we have updated the filtering attribute to be Quantity and Unit Price the field used by the Calculated column.
We updated both the Quantity and Unit Price and see the log generated i.e. plugin triggered.
The trace log –
While plugins can’t directly trigger on the calculated column changes, this workaround ensures we still get the desired automation.
Recently we observed that our plugin registered on the Delete message of appointment on the PreValidation stage was not getting triggered when we were deleting or updating the occurrence of the Recurring Appointment.
For both of the below operations, our plugin was not getting triggered. The plugin had the logic to delete a few associated records to the appointment record.
Delete operation – This deletes all the existing appointment.
Recurrence Update –This deletes the existing appointment and creates new appointment records based on the new recurrence.
On trying out different things, we saw that the plugin was getting triggered if registered on the PreOperation.
For testing, we registered a sample plugin that throws the InvalidPluginExecutionException and saw it getting triggered in case of PreOpertaion as shown below.
Recently we had a requirement to update the modifiedon date of a few of the records of notes table.
The we can achieve this is by implementing an update plugin on preoperation.
Below is our test record
Below is our plugin on the preoperation update to update the modifiedon date.
On updating the note record, we can see the modifiedon date updated as shown below.
Below are some other records where we have modifiedon updated (test records)
As we had multiple records to be updated on production, eventually we updated the plugin step to be triggered on the update of langid attribute (which won’t be updated by users) and used the awesome XrmToolBox Plugin – Bulk Data Updater to perform touch on langid field. This is to make sure it doesn’t get triggered on the creation or update of any existing records unless explicitly triggered from the Bulk Data Updater for that field and than disabled the plugin.
The BypassBusinessLogicExecutionStepIds optional parameter or request header value allows us to bypass a specific plugin step by passing its GUID, irrespective of whether it is synchronous or asynchronous, unlike the other optional parameters – BypassCustomPluginExecution and BypassBusinessLogicExecution that will bypass all the custom synchronous and/ or asynchronous logic (plugins and workflows).
Below we have our plugin registered, that writes to the Plugin Trace log.
The plugin step is registered on the update of the lead record. We have got the StepId of the plugin step from the Properties window.
Below is our console app, which updates the lead, triggering the plugin. On running it without the BypassBusinessLogicExecutionStepIds, we can see the trace log parameter record created.
Upon adding the BypassBusinessLogicExecutionStepIds parameter in UpdateRequest, as shown below, the plugin is not triggered and no trace log is created.
Also, we can pass multiple Step’s GUID to it
By default, we can maximum of 3 steps to it, which can be defined through BypassBusinessLogicExecutionStepIdsLimit Organization Settings value.
Using the new BypassBusinessLogicExecution parameter we can bypass both sync as well as asynchronous custom logic (i.e. sync / async custom plugin and custom workflow registered), unlike the BypassCustomPluginExecution parameter which applied to only the synchronous custom logic.
Let us see it in action with a simple example.
We have the following Plugin registered against the lead table that writes to the Plugin Trace Log.
We have the Update step (synchronous) registered for the plugin.
Below is our console app that updates one of the lead records triggering the plugin.
On running it we can see our plugin step triggered and a trace log created.
Now let us use the BypassCustomPluginExecution parameter of Update Request or BypassPluginExecution property of CrmServiceClient.
This time as expected the plugin is not triggered, so no plugin trace log record was created.
However, if our plugin step is registered in Asynchronous mode, we will have our plugin triggered, even if we are using the BypassCustomPluginExection parameter.
For bypassing the Asynchronous plugin only, or Sync Plugin, or both Async or Sync plugin, we can use the new optional parameter BypassBusinessLogicExecution passing the following values to it
CustomSync – to bypass synchronous logic.
CustomAsync – to bypass asynchronous logic.
CustomSync, CustomAsync – to bypass both Sync and Async logic.
On running the below code, our Plugin Step registered Asynchronously earlier is not triggered, in fact, any Synchronous step also, as we have specified both the CustomSync and CustomAsync.
“Also, any Workflow (Asynchronous or Real-time) registered will not trigger.“
In short,
BypassBusinessLogicExecution + CustomAsync parameter = Asynchronous workflow/plugin will be bypassed. We will have our Sync Plugin and Real-time workflow getting triggered.
BypassBusinessLogicExecution + CustomSync parameter or BypassCustomPluginExecution or BypassPluginExecution = Synchronous workflow/plugin will be bypassed. We will have our Asynchronous Plugin and Real-time workflow getting triggered
BypassBusinessLogicExecution + CustomSync + CustomAsync = Both Async / Sync Plugin and Workflow will be bypassed.
A few key points –
The user making the request needs to have the prvBypassCustomPlugins privilege.
These parameters will not apply to Core Plugin and Workflow included in a solution where Microsoft is the publisher.
Power Automate flows are not bypassed using these optional parameters.