Plug-in ServiceEndPoint Integration – Minimize IPluginExecutionContext payload

Integrating Microsoft Dynamics 365 with Azure Service Bus (ASB) can be easily implemented via the Plug-in Registration Tool without writing any code.
With this integration method, each time the target business event occurs, the complete operation IPluginExecutionContext payload is automatically sent to ASB, though often you need only a small portion of the data.

For some integration scenarios you need to apply conditional logic to decide if and which ASB queue to target. For these scenarios, you can write custom code which allows you to programmatically post message to ASB from Plug-in/Custom Workflow Activity components.
This method, also allows minimizing the IPluginExecutionContext payload which can simplify the logic required to parse it and generally improve performance. Unfortunately, I could not find a way to reduce the payload to just the required data, only minimize it.

The following screenshots (ASB Explorer) describes 2 similar messages (Contact creation event) posted to ASB before (4656 bytes) and after minimizing the IPluginExecutionContext payload (1842 bytes).
As you can see, the full payload weighs ~2.5 times the minimized payload.


To minimize the IPluginExecutionContext payload while maintaining the data you need, follow these simple steps in your code:

  1. Extract the required data from IPluginExecutionContext and add it to the SharedVariables collection
  2. Clear the data heavy IPluginExecutionContext collections
    • InputParameters
    • OutputParameters
    • PreEntityImages
    • PostEntityImages

The following sample code extracts the lastname attribute from the IPluginExecutionContext, clears the redundant collections and posts the minimized context to ASB:

        public void Execute(IServiceProvider serviceProvider)
        {
            // Retrieve the execution context.
            IPluginExecutionContext context = 
                (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));

            IServiceEndpointNotificationService cloudService = 
                (IServiceEndpointNotificationService)serviceProvider.GetService(typeof(IServiceEndpointNotificationService));

            // Extract the tracing service.
            ITracingService tracingService = (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            //extract target record data from InputParameters collection
            Entity contact = (Entity)context.InputParameters["Target"];
            //extract required data 
            string fullName = contact["lastname"].ToString();

            //add required data to the SharedVariables collection
            context.SharedVariables.Add("lastname", fullName);

            //clear redundant data from context 
            context.PreEntityImages.Clear();
            context.PostEntityImages.Clear();           
            context.InputParameters.Clear();
            context.OutputParameters.Clear();
            
            try
            {
                tracingService.Trace("Posting the execution context.");

                string response = cloudService.Execute(new EntityReference("serviceendpoint", 
                    serviceEndpointId),
                    context);
                
                if (!String.IsNullOrEmpty(response))
                {
                    tracingService.Trace("Response = {0}", response);
                }

                tracingService.Trace("Done.");
            }
            catch (Exception e)
            {
                tracingService.Trace("Exception: {0}", e.ToString());
                throw;
            }
        }
    }