Debugging Dynamics Plugins

Plugins have been around a long time in Dynamics and you either love them or strongly dislike them.

There isn’t much in between.

In working through a few issues on a recent project I had to build a plugin to tap into some many-2-many relationship joins.

If you are looking to solve a similar problem here are some links to get your started.

https://community.dynamics.com/crm/b/mscrmshop/archive/2012/05/14/how-to-trigger-a-plugin-for-many-to-many-relationship

https://community.dynamics.com/crm/b/mylifemicrosoftdynamiccrm/archive/2017/04/09/ms-dynamics-crm-associate-disassociate-message-plugin

In working on this problem I had to do a little more debugging in my plugins and was surprised to see the changes that have come in the Plugin Registration Tool.

To walk through your plugin’s execution, follow these steps.

  • Register your plugin.
  • If you have not already done it, Install the Plugin Profiler from the Plugin Registration Tool.
  • Before going back to Dynamics, Start the Plugin Profiler.

plug

  • Select your profile storage method (I left as recommended).
  • Now validate your code in Dynamics.  Upon completion you will be prompted with a file to download, save it.plug4
  • Now click on the “Replay Plug-In Execution” button at the top of the plugin tool.  The following window will appear where you will associate your downloaded plugin file and plugin.  Also note, that the tool tells you what PID (Process Id) the system is running as which will allow you to attach your Visual Studio process to, to walk through your code.

plug44

When you are ready, click “Start Execution”.

  • When executing you will see output akin to the following (where in my case the name of my plugin is called RecipientHandler.

plug444

This is a much easier, straight-forward and simpler way to debug plugins.  The step-through is great as you can then configure breakpoints in your code to see what Input/Output parameters you are working with and eliminate much of the guesswork.

 

Dynamics Quick Search

The easiest things to do are sometimes the hardest to find.

If you are frustrated with searching for your items in Dynamics via the Entity Search box even after enabling your field for search, you need to do one more step.  Go to your entity, navigate to the quick find view and then selecting the field you want to search on.

From there, you will then be able to search against your entity by the field(s) selected.

search

Easy to miss but easy to fix.

Disabling Quick Create

I ran into an issue the other day where I needed to turn off the usage of Quick Create forms and ensure that the standard forms would always be used for form creation.

The option to do this per entity is relatively simple – Navigate to your entity (via the solution) and uncheck the following entry.

ActivityPointerFail

Not a problem to do per entity, but it would be nice if there was a bulk, non-coding writing way to disable this functionality across all of your entities.  This is a good example of where these features can then be implemented across the board ensuring a consistent user experience.

ActivityPointer Redirection

I ran into error this a little while ago while doing some data conversions.

ActivityPointerFail

A quick search on Google will yield results on trying to associate an invalid activity record to your entity.

However this was not the case, as I was not doing any linking of activity records.

In the end what it turned out to be was that the relationship was created against Entity A (which was wrong), while I was passing in an EntityReference to Entity B.

Still wrong, still an error, but took me down the wrong path when the error first popped up.

And now you know.

Failed to Import Solution Error

I encountered a rather odd error the other day when I was having to do schema changes between organizations that involved a lot of importing and exporting when at one point I could not import the solution into one of my target orgs anymore.

After some digging through the Dynamics logs, the problem became very clear.

I had a field that had been incorrectly typed, so in my source org, I deleted it and recreated it.  When I proceeded to import the solution updates into my target org I could not perform the import because the field already existed but in an incompatible field type.

Specifically, doing some searching through very verbose CRM log file yielded the following entry.

Attribute new_legacyid is a Integer, but a String type was specified.

To get around this issue, I removed and deleted the field new_legacyid from my target org and then performed the import again, which then went smoothly from there.

 

Updating the State of a Record in Dynamics

Had some head banging to do this past week when I wanted to update the state of a record in Dynamics.  For some reason, this has always been an indirect path to accomplishing a simple task.

This article applies only to Dynamics 2015/2016 and below.  In Dynamics365, this method is being deprecated in place of the Update method (YES)!

Before you code anything, there are two references you are going to need in order to access the correct object.

Microsoft.Crm.Sdk.Proxy

Microsoft.Xrm.Sdk

Now that you have those two references you can now leverage the SetStateRequest message to submit your state change (after your entity was created).

 SetStateRequest request = new SetStateRequest();
 request.EntityMoniker = new EntityReference("your_entity_name", EntityId);
 request.State = new OptionSetValue(1);
 request.Status = new OptionSetValue(2);
 
 svc.Execute(request);

In the above, EntityId is the primary id (guid) of the record that was created.  The 1 and 2 are values represent the statecode and statusreasons fields in your system, while statecode will generally be the same (Active = 0, InActive = 1), statusreason can be wildly different.

An informative list of status codes are available here.

Dynamics Workflow Scope

I ran into a scenario this week, where  workflow I created was only running for my user account on records that I had created and not ones that I might later modify and/or that other people had created.

The solution was to change the scope of the workflow to Organization so it ran for everyone.

Changing from User (the default) to Organization got this going.  I haven’t had a need to try with the current user’s business unit which would be pretty cool too.

org