Search This Blog

Friday, March 4, 2022

Dynamics 365 CRM Plug-ins

 Here we will discuss below points regarding CRM plugins.

  • Plugin Concept
  • Sample Task
  • Build, Deploy & Debug, Test
  • Release
  • Best Practice
  • Exception handling

Plugin Concept

  • Plugins are custom business logic or code which modifies the default behavior of CRM platform.
  • This requires .net c# programming concept and a developer knowledge with CRM SDK knowledge.
  • As a technical term Plugin is a .net class library(.dll) which uses the reference of Microsoft.Xrm.Sdk.dll and Microsoft.Crm.Sdk.Proxy assembly to interact with CRM Organisation to achieve the task. You can find it in CRM SDK\bin folder which you can download Freely here by choosing correct version of CRM SDK.
  • As plugin interacts with CRM service so System.Runtime.Serialization namespace is required.
  • Plugin are also called as CRM Event Handlers which reacts on events raised by CRM platform. Events are like Create Record, Update Record, Retrieve Record, Delete Record etc..
  • Plugins follow an Event Execution Pipeline model of CRM as snapshot given below.




event.jpeg

  • CRM SDK also contains sample codes to refer for developers to start plugins. Also you can follow here to check out sample plugin code structure.
  • Plugins can be registered in below Stages Pre-Validation, Pre-Operation, Post-Operation. But cannot be registered again main core operation. Checkout the below image for understanding the stages.
  • As plugins are nothing but .net assemblies the output of the plugin is a .dll file. Plugins class implements an Interface called as IPlugin interface and the method Execute must be implemented which takes IServiceProvider parameter.

events.png

  • Plugin Context

    • When a plug-in runs in response to an execution pipeline event for which it is registered, the plug-in’s Execute method is called. That method passes an IServiceProvider object as a parameter, which contains a number of useful objects.The sample is given below. to understand the context more checkout the topic here.
      public class MyPlugin: IPlugin
      { public void Execute(IServiceProvider serviceProvider){ //code here} }
    • By the below code you can get the context from the service provider object.
      // Obtain the execution context from the service provider.
      IPluginExecutionContext context = (IPluginExecutionContext)
          serviceProvider.GetService(typeof(IPluginExecutionContext));
    • The context contains the Entity information on which it is being registered. The context has properties like InputParameters & OutPutParameters.
  • Plugin Impersonation

    • By default plugins are set to run as calling user but sometimes we run the plugins using System user with highest privilege this is called Impersonation in plugin.
    • We can set Run in Context property for Plugins Impersonation while registering the plugin.
    • on Impersonation in plugin Hosk has written a nice article check out here.
  • Signing the plugin assembly

    • Every plugin must be signed by a Key. This signing process generates a certificate for the assembly.
    • We can do this by the properties option of the plugin in Signing option.key
  • Plugin registration tool

    • Plugin registration tool is available in the CRM SDK folder. This tool provides a flexible way to register our plugins.
    • In this tool we can set the message and add steps for the plugin assembly. Also we can set the Plugin execution order, Impersonation etc.
    • Plugins and Custom Workflow activities both can be registered using this tool.
  • Privilege for Register

    • Plugins can be developed by any user who know coding but to deploy or register the plugin in CRM you have to be added in the Deployment Manager group.
  • Plug-in isolation

    • Plugins which are registered in isolation have no access to file system access and network access.
    • Plugins which are targeted for online version of CRM must be registered in Isolation and for On-premise version the isolation is not required.
  • Shared variables

    • Shared variables are the plugin variables which can be identified by multiple plugins. Using this option we can pass data from one plugin to another.
    • A Pre-operation registered plugin can send data to a post-operation registered plugin using shared variables.
  • Messages

    • Messages are nothing but events that are raised in CRM platform. There is an exhaustive list of events that are generated in CRM. The list is given in CRM SDK for reference.
  • Images Pre & Post Images)
    • Images are snapshots of the entity record. In CRM have two images type Pre and Post images.
    • Pre-Image contains the record snapshot of the current data from database.
    • Post-Image is the snapshot of the updated and recent data passed in the context.
    • There is no Pre-Image for a Create event.
    • There is no Post-Image for a Delete event.
    • For an Update event we have both Pre and Post Images, we can configure this images in plugin registration tool while registering the plugin.
  • Sync/Async

    • Plugins can be synchronous or asynchronous. synchronous plugins runs immediately and the processing system waits till the plugin completes execution so in this case user has to wait for the completion of plugin.
    • Asynchronous plugins runs in background like workflows when the system is free.
  • 2mins TimeOUT

    • Plugins are developed to run as quick as possible. synchronous plugins are part of core operation thread so runs immediately and user has to wait till the plugin completes successfully.
    • If the Plugin is developed with heavy and time consuming codes and it exceeds 2minutes then it fails executing throwing a TimeOUT error resulting the process roll back in that specific transaction.
    • The plugin runs in one transaction so any error or exception rolls back the whole process.
    • SO be careful while designing plugins considering its load and processing options.
  • Registration options

    • Plugins can be registered in 3 locations
      • Database : assembly stores in SQL organization database
      • Disk : assembly will be stored in the Installation directory of CRM in Server\Bin
      • GAC : Assembly will be stored in System Global Assembly Cache in windows.

Sample Task – Practical

Lets take a scenario and develop a plugin from scratch for a better understanding.

  • Scenario
  • Requirement
  • Solution

Scenario: There is a Invoice entity with attributes (amount(money), terms(int), Invoiceday(int) ). There is another entity InvoiceDetail with attributes (amount(money), Invoicedate(datetime)).

Invoice (1) : Invoice Detail (N)

1n.png

Requirement : When a user will create a Invoice record with all field values then terms field value number of Invoice detail records will be created.

E.g. :if terms =12, amount=24.00, invoiceday=1 then 12 payment detail records will be created with amount=2 i.e. (24/12), Invoicedate =1st of next month with year, accordingly upto 12 month.

Build, Deploy & Debug, Test

  • References & SDK
    • For building Plugins as discussed above download CRM SDK.
    • Add required references to the plugin as specified above and refer the sample code folder of CRM SDK for more information.assemblies.png
  • Visual Studio Class library
    • Plugin is nothing but a .net class library so the project type should be chosen as a Class library project.
    • Set the .net framework correctly as given screenshot.
  • Context Depth
    • Sometimes Plugins executed for infinite loop so to stop the plugin running from infinite loop we have to check context.Depth property.
    • To run the plugin only once just add a condition context.Depth <1 then pass the control to your logic.
  • Deploy/Registration
    • Plugins are registered in CRM using Plugin Registration Tool by creating a connection to target environment.
    • These Plugins and Steps are added to the CRM Solution for Deployment in Upstream environments.
  • Debugging, attach process
    • To Debug Plugin we have to attach the process called as w3wp.exe and giving breakpoint to debug line by line.
    • For Custom Workflow or Async Plugins attach CRMAsyncService.exe process
    • Follow this article to know more about Plugin Debug.
  • Remote Debugging
  • Plugin Profiler
  • Developer Toolkit
    • The Developer Toolkit is a set of Microsoft Visual Studio 2010 and Microsoft Visual Studio 2012 integration tools focused on accelerating the development of custom code for Microsoft Dynamics CRM. Read detail article here.
  • Plugin Testing
    • To test plugins personally I prefer to define some sample batch job to test if the codes written in the plugin works fine or not.
    • There are also some frameworks available for testing Plugins like Fake XRM.

Release

pluginss

  • Adding in Solution
    • Plugins and Steps are added to a solution for deployment.
  • Exporting Solution
    • From Development environment the solution should be exported for up-stream environment.
  • Plugin Execution Order
    • If multiple plugins are registered on the event of an entity then we can set the Execution order of the plugins to run one by one according to the need.
    • If Execution orders are not specified then by default the plugins will run according to their registration date.
  • Filtering Attributes
    • When registering a plugin on an update message/event then it is best practice to specify the filtering attributes to trigger plugin otherwise the plugin will run on any field update which may cause unwanted issues.

Best Practice & Performance

  • Async/Sync Consideration
    • While developing plugins developers should validate the plugins if this runs synchronously or asynchronously.
    • If synchronous then you have to consider the plugin to be light weight which runs faster otherwise timeout errors will be thrown.
    • If Asynchronous plugin then we have to consider if there is any error then system job will capture the errors and users will not be notified immediately.
  • Exception handling Consideration & Notification Service
  • Infinite loop consideration
    • Always check if your plugin runs infinite loop if so then use context depth to restrict this.
  • Code optimization
    • Write simple codes as much as possible.If we refer any external service then dont forget to close the connection. Dont use heavy weight objects causing the plugin slowdown.
  • Performance optimization

Exception Handling

  • Try Catch throw
    • Always use try….catch block to catch specific runtime exceptions.
    • Throw user understandable messages.
  • Invalid Plugin Execution
    • In Plugins always throw errors of type InvalidPluginExecution error.
  • Logging system
    • In Plugins we can use Error or Info Entities to log information.
  • Tracing
    • In Plugins we can specify tracing using ITracing interface.
  • Window Event Viewer Entry
    • Some runtime unhandled exceptions with detailed tracing are logged in windows event viewer.

Clone any Record Dynamics 365/Step By Step Creating a Simple Plugin

 I was working on a requirement where i have to clone records on multiple custom entities.if the entity having very less fields, you can achieve it easily but what about those entities where attributes are more than 100 per entity. So, i am going to tell you how you can achieve it easily by writing a very small code.

Lets start!

Step-1: Add a button “Clone” using the ribbon workbench on your entity where you want to perform the cloning. Just drag and drop where you want to add.

Now create a command and add an java script action.

Add java script library and function name(code added below). Add a “Crm Parameter= PrimaryControl”.

After that add the command to the button. Publish the solution from ribbon workbench.

Step-2: Now create a global Action process inside your dynamics solution.and create a input parameter of “Entity” type .

we are going to set it through our java script code as below. So while setting the entity type parameter inside the action, we need to specify two properties , 1) GUID of the record , 2) Logical name in key value pair.

Note: Value you can get easily but how you can make “key” dynamic so that it could run on any custom entity. for that you need to pass the key dynamically as shown in below code(check InvokeAction function parameter).

function callAction(primaryControl) {
    debugger;
    var formContext=primaryControl;
    var formtype = formContext.ui.getFormType();
    if(formtype!=1){
    debugger;
    Xrm.Utility.confirmDialog("Do You want Clone this Record?", 
    function () {
     var recordId = formContext.data.entity.getId().replace("{", "").replace("}", "");
     var logicalName = formContext.data.entity.getEntityName();
    InvokeAction(recordId,logicalName);
    },
    function () {});
    
    } 
   }
   function InvokeAction(recordId,logicalName) {
    debugger;
    var parameters = {};
var target = {};
target[logicalName+"id"]=recordId;      //making it dynamics so can be worked on multiple entity
target["@odata.type"] = "Microsoft.Dynamics.CRM."+logicalName;
parameters.Target = target;

var ign_CloneRecordRequest = {
    Target: parameters.Target,

    getMetadata: function() {
        return {
            boundParameter: null,
            parameterTypes: {
                "Target": {
                    "typeName": "mscrm.crmbaseentity",
                    "structuralProperty": 5
                }
            },
            operationType: 0,
            operationName: "ign_CloneRecord"            //specify your action name
        };
    }
};

Xrm.WebApi.online.execute(ign_CloneRecordRequest).then(
    function success(result) {
        if (result.ok) {
            //Success - No Return Data - Do Something
        }
    },
    function(error) {
        Xrm.Utility.alertDialog(error.message);
    }
);
    
   }
   

Step-3:After that you need to create a plugin which will create a clone/copy of the record.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Crm.Sdk.Messages;

namespace cloneRecord
{
    public class cloneRecord : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {

            IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
            ITracingService tracing = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
            IOrganizationServiceFactory servicefactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
            IOrganizationService service = servicefactory.CreateOrganizationService(context.UserId);
            tracing.Trace(context.InputParameters.Contains("Target").ToString());
            if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
            {
                if(context.Depth>1)
                {
                    return;
                }
                //Getting the Entity record from the Action
                Entity en = (Entity)context.InputParameters["Target"];
                //Retrieving the same entity record with all the attributes
                Entity entity= service.Retrieve(en.LogicalName, en.Id, new ColumnSet(true));
                //Set the EntityState to null, so that a new cloned record can be created
                entity.EntityState = null;
                //remove the PrimaryId of the record otherwise will show you error
                entity.Attributes.Remove(entity.LogicalName+"id") ;

                if(entity.Contains("new_name") && (string)entity.Attributes["new_name"]!=string.Empty)
                {
                    //differentiating the new record which will create from the exisiting with New prefix.
                    entity.Attributes["name"] = "New " + entity.Attributes["name"].ToString();
                }

                //set a unique id to the cloned record
                entity.Id = Guid.NewGuid();

                //Create the new cloned record
                service.Create(entity);
            }
            }
    }
}

Now register your plugin and use the global action as message inside your plugin step.

Now navigate to custom entity in dynamics model driven app. As you can see here my clone button just click on it.

Now go back to the Entity list record and you will found copied/cloned record as below image. If you want to do cloning of record more than one entity, just follow only the Step-1 as shown above, it will work for any entity.

That’s it.

Step By Step Creating a Simple Plugin

  1. What is a Plugin?
  2. When to use the Plugins?

1. What is a Plugin?

A plug-in is custom business logic(code) that you can integrate with Dynamics CRM to modify or augment the standard behavior of the platform.

In simple word, it is a piece of code used to enhance the ability to perform the task which we can not do by of box customization.

Plugins are event handlers for the events fired by Microsoft Dynamics CRM.

You can register plug-in against events using Plugin registration tool or using Solutions.

The plug-in runs in CRM server synchronous(in real time) or asynchronously(in the background) depends upon how they are registered with CRM server.

2. When to use the Plugins?

Plugins Vs JavaScript

  • When Server Side execution of business logic is needed.

Plugins Vs Workflows

  • Workflows can be used to trigger for a limited number of messages(events). A plugin can be executed for all of the messages of the CRM system and can be synchronous and asynchronous.
  • When the performance is considered.

Let’s Begin with An Example:

A plug-in is a custom business logic that integrates with Microsoft Dynamics CRM to modify or extend the standard behavior of the platform. Plug-ins act as event handlers and are registered to execute on a particular event in CRM. Plugins are written in either C# or VB and can run either in synchronous or asynchronous mode.

Some scenarios where you would write a plugin are −

  • You want to execute some business logic such as updating certain fields of a record or updating related records, etc. when you create or update a CRM record.
  • You want to call an external web service on certain events such as saving or updating a record.
  • You want to dynamically calculate the field values when any record is opened.
  • You want to automate processes such as sending e-mails to your customers on certain events in CRM.

Event Framework

The Event Processing Framework in CRM processes the synchronous and asynchronous plugin requests by passing it to the event execution pipeline. Whenever an event triggers a plugin logic, a message is sent to the CRM Organization Web Service where it can be read or modified by other plugins or any core operations of the platform.

Plugin Pipeline Stages

The entire plugin pipeline is divided into multiple stages on which you can register your custom business logic. The pipeline stage specified indicates at which stage of the plugin execution cycle, your plugin code runs. Out of all the specified pipeline stages in the following table, you can register your custom plugins only on Pre- and Post-events. You can’t register plugins on Platform Core Main Operations.

EventStage NameStage Name
Pre-EventPre-validationStage in the pipeline for plug-ins that are to execute before the main system operation. Plug-ins registered in this stage may execute outside the database transaction.
Pre-EventPre-operationStage in the pipeline for plug-ins that are to executed before the main system operation. Plugins registered in this stage are executed within the database transaction.
Platform Core OperationMainOperationIntransaction,the main operation of the system, such as create, update, delete, and so on. No custom plug-ins can be registered in this stage. For internal use only.
Post-EventPost-operationStage in the pipeline for plug-ins which are to executed after the main operation. Plug-ins registered in this stage are executed within the database transaction.

Whenever the CRM application invokes an event (like saving or updating a record), the following sequence of actions takes place −

  • The event triggers a Web service call and the execution is passed through the event pipeline stages (pre-event, platform core operations, post-event).
  • The information is internally packaged as an OrganizationRequest message and finally sent to the internal CRM Web service methods and platform core operations.
  • The OrganizationRequest message is first received by pre-event plugins, which can modify the information before passing it to platform core operations. After the platform core operations, the message is packaged as OrganizationResponse and passed to the post-operation plugins. The post operations plugins can optionally modify this information before passing it to the async plugin.
  • The plugins receive this information in the form of context object that is passed to the Execute method after which the further processing happens.
  • After all the plugin processing completes, the execution is passed back to the application which triggered the event.

Plugin Messages

Messages are the events on which the plugin (or business logic) is registered. For example, you can register a plugin on Create Message of Contact entity. This would fire the business logic whenever a new Contact record is created.

For custom entities, following are the supported messages based on whether the entity is user-owned or organization-owned.

Message NameOwnership Type
AssignUser-owned entities only
CreateUser-owned and organization-owned entities
DeleteUser-owned and organization-owned entities
GrantAccessUser-owned entities only
ModifyAccessUser-owned entities only
RetrieveUser-owned and organization-owned entities
RetrieveMultipleUser-owned and organization-owned entities
RetrievePrincipalAccessUser-owned entities only
RetrieveSharedPrincipalsAndAccessUser-owned entities only
RevokeAccessUser-owned entities only
SetStateUser-owned and organization-owned entities
SetStateDynamicEntityUser-owned and organization-owned entities
UpdateUser-owned and organization-owned entities

For default out-of-the-box entities, there are more than 100 supported messages. Some of these messages are applicable to all the entities while some of them are specific to certain entities. You can find the complete list of supported message in an excel file inside the SDK: SDK\Message-entity support for plug-ins.xlsx

Writing Plugin

In this section, we will learn the basics of writing a plugin. We will be creating a simple plugin that creates a Task activity to follow-up with the customer whenever a new customer is added to the system, i.e. whenever a new Contact record is created in CRM.

First of all, you would need to include the references to Microsoft.Xrm.Sdknamespace. The CRM SDK contains all the required SDK assemblies. Assuming that you have already downloaded and installed the SDK in Chapter 2, open Visual Studio. Create a new project of type Class Library. You can name the project as SamplePlugins and click OK.

Mscrm Plugin Create vs Solution

Add the reference of Microsoft.Xrm.Sdk assembly to your project. The assembly is present in SDK/Bin.

Mscrm Plugin Add Solution Reference

Now, create a class named PostCreateContact.cs and extend the class from IPlugin. Till now, your code will look something like the following.

Mscrm Plugin Sample Code

You will also need to add reference to System.Runtime.Serialization. Once you have added the required references, copy the following code inside the PostCreateContact class.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xrm.Sdk;

namespace SamplePlugins {
   public class PostCreateContact:IPlugin {
      /// A plug-in that creates a follow-up task activity when a new account is created.
      /// Register this plug-in on the Create message, account entity,
      /// and asynchronous mode.

      public void Execute(IServiceProviderserviceProvider) {
         // Obtain the execution context from the service provider.
         IPluginExecutionContext context =(IPluginExecutionContext)
            serviceProvider.GetService(typeof(IPluginExecutionContext));

         // The InputParameters collection contains all the data
            passed in the message request.

         if(context.InputParameters.Contains("Target")&&
            context.InputParameters["Target"]isEntity) {
            
            // Obtain the target entity from the input parameters.
            Entity entity = (Entity)context.InputParameters["Target"];
            try {
               
               // Create a task activity to follow up with the account customer in 7 days
               Entity followup = new Entity("task");
               followup["subject"] = "Send e-mail to the new customer.";
               followup["description"] =
                  "Follow up with the customer. Check if there are any new issues
                  that need resolution.";
               
               followup["scheduledstart"] = DateTime.Now;
               followup["scheduledend"] = DateTime.Now.AddDays(2);
               followup["category"] = context.PrimaryEntityName;

               // Refer to the contact in the task activity.
               if(context.OutputParameters.Contains("id")) {
                  Guid regardingobjectid = new Guid(context.OutputParameter
                     s["id"].ToString());
                  string regardingobjectidType = "contact";
                  followup["regardingobjectid"] = 
                     new EntityReference(rega rdingobjectidType,regardingobjectid);
               }
               
               // Obtain the organization service reference.
               IOrganizationServiceFactory serviceFactory =
                  (IOrganizationSer viceFactory)serviceProvider.GetService
                  (typeof(IOrganizationServiceFactory));
               IOrganizationService service = 
                  serviceFactory.CreateOrganizationService(context.UserId);

               // Create the followup activity
               service.Create(followup);
            } catch(Exception ex) {
               throw new InvalidPluginExecutionException(ex.Message);
            }
         }
      }
   }
}

Following is a step-by-step explanation of what this code does −

Step 1 − Implements the Execute method by taking IServiceProvider object as its parameter. The service provider contains references to many useful objects that you are going to use within a plugin.

Step 2 − Obtains the IPluginExecutionContext object using the GetService method of IServiceProvider.

Step 3 − Gets the target entity’s object from the context object’s InputParameters collection. This Entity class object refers to the Contact entity record on which our plugin would be registered.

Step 4 − It then creates an object of Task entity and sets a proper subject, description, dates, category, and regardingobjectid. The regardingobjectid indicates for which contact record this activity record is being created. You can see that the code gets the id of the parent Contact record using context.OutputParameters and associates it with the Task entity record which you have created.

Step 5 − Create an object of IOrganizationServiceFactory using the IServiceProvider object.

Step 6 − Create an object of IOrganizationService using the IOrganizationServiceFactory object.

Step 7 − Finally, using the Create method of this service object. It creates the follow-up activity which gets saved in CRM.

Signing the Plugin Assembly

This section is applicable only if you are registering your plugin assembly for the first time. You need to sign in the assembly with a key to be able to deploy the plugin. Rightclick the solution and click Properties.

Mscrm Plugin Solution Properties

Select the Signing tab from the left options and check the ‘Sign the assembly’ option. Then, select New from Choose a strong name key file option.

Mscrm Plugin Sign Assembly

Enter the Key file name as sampleplugins (This can be any other name you want). Uncheck the Protect my key file with a password option and click OK. Click Save.

Mscrm Plugin Sign Assembly Add Key

Finally, build the solution. Right Click → Build. Building the solution will generate assembly DLL, which we will use in the next chapter to register this plugin.

Exception Handling in Plugin

More often than not, your plugin logic will need to handle run-time exceptions. For synchronous plugins, you can return an InvalidPluginExecutionException exception, which will show an error dialog box to the user. The error dialog will contain the custom error message that you pass to the Message object of the exception object.

If you look at our code, we are throwing the InvalidPluginExecutionException exception in our catch block.

throw new InvalidPluginExecutionException(ex.Message); 
Dynamics 365 CRM Plugin Messages

What is a Message?

If you are new to Dynamics CRM development, a Message word that is used to instruct CRM to do something. As far as I can tell, since the early versions of the CRM SDK used the SOAP protocol exclusively, and SOAP passes messages, the term message became the standard name for CRM internal processing options

If anyone has any other explanation, please let me know and I’ll update the post.

What do you do with Messages?

Messages are what a plugin “listens for” to know when to activate and perform whatever job it was programmed to do.

A Message is associated with a Plugin Step ( internally called a SdkMessageProcessingStep ), which is a pointer that associates your plugin code to a Dynamics CRM internal action.

Inside the Plugin Registration Tool, you may see something like this:

image

As you can see, I have an assembly called ClassLibrary1, within that assembly I have a single plugin, SamplePlugin, and that plugin has two steps:

  1. Create of a queue item
  2. Create an email

Create is the Message.

How do I make it GO?

So, how do you, as a plugin developer, figure out what message you need to use to properly configure your plugin?

Well, for the most part, it’s pretty simple: You select the CRM operation you are interested in intercepting then select Entity that will be associated with that Message.

Here is how the configuration looks within the Plugin Registration Tool:

image

But what if I don’t know what message to use?

Excellent question, and the reason for my article.

The very fine folks in the Dynamics CRM documentation team have created for us, an Excel worksheet that lists all of the messages associated with a CRM Entity.

After you install the CRM SDK, you’ll find the worksheet here:

sdk\tools\message-entity support for plug-ins.xlsx

And here is how it looks:

image

It lists the following information:

  • Message Name
  • Primary Entity
  • Secondary Entity
  • Message Availability
  • Server or
  • Both – for Client and Server
  • Entity Supported Deployment
  • Server or
  • Both – for Client and Server

How do I use it?

Usually, I know what Entity I am going to work with so I start there and filter the Primary Entity-based on that information.

Next, I try and locate the Message Name that I might need. Now, this sounds simple, but in certain cases, it’s really hard to determine what exact message you should connect with.

In that case, I will sometimes create steps that monitor each possible message, connect my debugger to IIS, then execute the CRM operation of interest so that I see what message is actually being passed through to my plugin.

You can find the message in the Execution Context’s MessageName property.

Option 2

A second option is to look in the SDK help file itself for topics like:

Email (E-mail) Entity Messages and Methods

Where you will find information like this:

image

This should be the same (mostly) list of Messages found in the Excel file. Just remove the word “Request” from the end of the Message Name found in the SDK help file and you should have a match.