Search This Blog

Friday, September 30, 2022

Pre-Image and Post-Image in Dynamics CRM

 image

 What is Pre and Post Images in CRM?

 In Real Life,

 Let's understand the Images in CRM by taking one real-life example of ATM Withdrawal Process:

 

Suppose, I have 10,000 Rs in my bank account. So this amount would be the Pre-Image of my account balance. Now, If I withdraw 5000 Rs from my account, then the remaining amount left in my account would be 5000 Rs. So the current amount left in my account would be the Post-Image of my account balance.

 

Here

 

image

Pre-Image of my Account Balance = 10,000 Rs

image

Performing Database Transaction

image

Transaction Done (Core Operation) of 5000Rs

image

Post-Image of my Account Balance = 5000 Rs

 

In CRM,

  • Images are the snapshots of the entity's attributes, before and after the core system operation. 
  • PreEntityImages contain snapshots of the primary entity's attributes before the core platform operation perform and PostEntityImages contains the snapshot of the primary entity's attributes after the core platform operation performed.

Let say: I have a contact record in the CRM with FirstName and LastName as Arpit and Shrivastava respectively. Suppose I change the values of both the field as Mike and Hussey respectively. Then the  Pre-Image of FirstName and LastName would be Arpit and Shrivastava respectively while the Post-Image of FirstName and LastName would get Mike and Hussey respectively.

Difference between Plugin Context and Plugin Images? 

 Context means Current.

 Context contains the entity business information which is being updated currently on CRM Platform.

In Plugin,

IPluginExecutionContext contains information that describes the run-time environment that the plug-in executes, information related to the execution pipeline, and entity business information.

When a system event is fired that a plug-in is registered for, the system creates and populates the context and passes it to a plug-in through the previously mentioned classes and methods. The execution context is passed to each registered plug-in in the pipeline when they are executed.

Context Example - 

Let say. I have a plugin registered on Update of Contact Entity, If I update only Firstname and Lastname of contact record then plugin code can get only Firstname and Lastname field's value from the Plugin Context along with the information related to the execution pipeline.

But If I want to get the other field's value like emailaddress and account name from plugin context, we will not be able to get the same and will get the error 'The given key was not present in the dictionary' error.

To get these values, either we will have to perform retrieve query or can achieve it through pre-images.

So Images are the best ways to get the copy of data (from whatever fields you want) before and after changes made to the database or changes committed to the database. While from context we can get the updated field's values only

Advantages of using Pre-Image and Post-Image in CRM?

 

One of the best uses for this is in update plug-ins. 

  • In update plug-in, target entity only contains the updated attributes. However, often the plug-in will require information from other attributes as well. Instead of issuing a retrieve, the best practice is to push the required data in an image instead.

For Example- I have a plugin trigger on Update of Account's email address and website fields. 

Logic is if any user updates the account's email address and website URL then, create a task with the updated email address and website URL along with account name and its parent account.

To implement this logic in my plugin, I can get account's email address and website URL from Context while account name and parent account.not. Because the user has updated only account's email address and website URL not rest of the account's data. So Plugin Context contains only updated information instead of unchanged information.

So how would I get the account's account name, parent account or any other data?

Option 1- Perform Retrieve Query to get rest of account information.

Option 2- Use Pre-Image and configure the fields from which we want to pull the information without performing any query on the database.

 Comparison of data before and after. This allows for various audit-type plugins, that logs what the value was before and after, or calculating the time spent in a stage or status.

 

When are the different images available in the event execution pipeline? 

 

image

 Plugin Image Example:

 

Let understand the plugin code by taking a very simple example- 

 

Whenever a user updates the emailaddress and topic(subject) on the Lead entity, we want to get the old and new value respectively of the topic field before and after the changes made in the database. And update both the values in the description field.

 

So here, the old value of topic field would be called as pre-image and the new value of topic field would be called as post image.

 

Register a Plugin on Update of Lead 'Email Address' Field.

 

image

 

Register a new Image on Update Step

 

image

  

Select 'Topic' from the Field List. Because we want to get the Pre and Post Image of Topic Field.

 

image

 

Give Image name and check PreImage and PostImage checkbox

 

You can specify to have the platform populate these PreEntityImages and PostEntityImages properties when you register your plug-in. The entity alias value you specify during plug-in registration is used as the key into the image collection in your plug-in code

image

using Microsoft.Xrm.Sdk;

using Microsoft.Xrm.Sdk.Query;

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;


namespace PluginImageExample
{

 public class LeadUpdate : IPlugin

  {

    public void Execute(IServiceProvider serviceProvider)

    {

    // Extract the tracing service for use in debugging sandboxed plug-ins.

    ITracingService tracingService =

    (ITracingService)serviceProvider.GetService(typeof(ITracingService));


    // Obtain the execution context from the service provider.

    IPluginExecutionContext context = 
    (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
   // Obtain the organization service factory.
   
    IOrganizationServiceFactory serviceFactory = 

    (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));

    
    // Obtain the organization service.    
    IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);


    if (context.InputParameters.Contains("Target") && 

                  context.InputParameters["Target"] is Entity)

     {

        // Obtain the target entity from the input parameters.

         Entity entity = (Entity)context.InputParameters["Target"];

        // User is updating only email address in lead form so we will get only 
           emailaddress from the context not lead's description.To get description
           orsubject field we will use plugin images
        // get the lead email from context.

         string email = entity["emailaddress1"].ToString();

        // get the current record guid from context

         Guid leadRecordGuid = entity.Id;
  // Define variables to store Preimage and Postimage  string pretopic = string.Empty; string posttopic = string.Empty; 

        // in below leadimage has been added in plugin registration tool

        // get PreImage from Context

          if (context.PreEntityImages.Contains("LeadTopicImage") && context.PreEntityImages["LeadTopicImage"] is Entity)
          {

                Entity preMessageImage = (Entity)context.PreEntityImages["LeadTopicImage"];
               // get topic field value before database update perform
                pretopic = (String)preMessageImage.Attributes["subject"]; 

}



// get PostImage from Context
            if (context.PostEntityImages.Contains("LeadTopicImage") && 
                   context.PostEntityImages["LeadTopicImage"] is Entity)

            {

              Entity postMessageImage = (Entity)context.PostEntityImages["LeadTopicImage"];

              // get topic field value after database update performed
             posttopic = (String)postMessageImage.Attributes["subject"]; 

}


// update the old and new values of topic field
in description field

          Entity leadObj = 
          service.Retrieve(context.PrimaryEntityName,leadRecordGuid, new ColumnSet("description"));

          leadObj["description"] = 
          "Pre-Image of description- "+pretopic+"   "+"Post-Image of description-- "+posttopic;

          service.Update(leadObj);

           }

        }

    }

}


Let's test the functionality. Open any existing Lead record.

 

image




Update Email and Topic field's value and Save the record.

 

image


Check the 'Description' field. It has been updated with old and new value both of Topic Field.

 

image

 

Points to Note:

                                                                      image

  • Microsoft Dynamics 365 populates the pre-entity and post-entity images based on the security privileges of the impersonated system user. Only entity attributes that are set to a value or are null are available in the pre or post entity images. 
  • There are some events where images aren’t available. For example, only synchronous post-event and asynchronous registered plug-ins have PostEntityImages populated. The create operation doesn’t support a pre-image and a delete operation doesn’t support a post-image.
  • Registering for pre or post images to access entity attribute values results in improved plug-in performance as compared to obtaining entity attributes in plug-in code through RetrieveRequest or RetrieveMultipleRequest requests.
  • A pre-image passed in the execution context to a plug-in or custom workflow activity might contain data that the logged-on user doesn't have the privileges to access. Microsoft Dynamics 365 administrators and other users with high-level permissions can register plug-ins to run under the “system” user account or plug-in code can make calls as a “system” user on behalf of the logged-on user. If this happens, logged-on users can access data that their field level security does not allow access to.
  • Context contains only updated field's value information of any record. While the Pre-Image contains all the field's values information (depends on what field you are being opted to be available as pre-images)

No comments:

Post a Comment