Understand the data context passed to a plug-in


Updated: November 29, 2016

Applies To: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2016, Dynamics CRM Online

When a plug-in is run 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 following sections describe some of the information that is passed to a plug-in when executed.

IPluginExecutionContext contains information that describes the run-time environment that the plug-in executes, information related to the execution pipeline, and entity business information. The context is contained in the System.IServiceProvider parameter that is passed at run time to a plug-in through its Execute method.

// Obtain the execution context from the service provider.
IPluginExecutionContext context = (IPluginExecutionContext)

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. Each plug-in in the execution pipeline is able to modify writable properties in the context. For example, given a plug-in registered for a pre-event and another plug-in registered for a post-event, the post-event plug-in can receive a context that has been modified by the pre-event plug-in. The same situation applies to plug-ins that are registered within the same stage.

All the properties in IPluginExecutionContext are read-only. However, your plug-in can modify the contents of those properties that are collections. For more information about infinite loop prevention, see Depth.

To access the Microsoft Dynamics 365 organization service, it is required that plug-in code create an instance of the service through the ServiceProvider.GetService method.

// Obtain the organization service reference.
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);

The platform provides the correct web service URLs and network credentials for you when you use this method. Instantiating your own Web service proxy is not supported as it will create deadlock and authentication issues.

Synchronous registered plug-ins can post the execution context to the Microsoft Azure Service Bus. The service provider object that is passed to the plug-in contains a reference to IServiceEndpointNotificationService. It is through that notification service that synchronous plug-ins can send brokered messages to the Microsoft Azure Service Bus. For more information about Microsoft Azure, see Azure integration with Microsoft Dynamics 365. For more information about writing a plug-in that can post to the Microsoft Azure Service Bus, see Write a custom Azure-aware plug-in.

The InputParameters property contains the data that is in the request message currently being processed by the event execution pipeline. Your plug-in code can access this data. The property is of type ParameterCollection where the keys to access the request data are the names of the actual public properties in the request. As an example, take a look at CreateRequest. One property of CreateRequest is named Target, which is of type Entity. This is the entity currently being operated upon by the platform. To access the data of the entity you would use the name “Target” as the key in the input parameter collection. You also need to cast the returned instance.

// The InputParameters collection contains all the data passed in the message request.
if (context.InputParameters.Contains("Target") &&
    context.InputParameters["Target"] is Entity)
    // Obtain the target entity from the input parameters.
    Entity entity = (Entity)context.InputParameters["Target"];

Note that not all requests contain a Target property that is of type Entity, so you have to look at each request or response. For example, DeleteRequest has a Target property, but its type is EntityReference. The preceding code example would be changed as follows.

// The InputParameters collection contains all the data passed in the message request.
if (context.InputParameters.Contains("Target") &&    context.InputParameters["Target"] is EntityReference)
    // Obtain the target entity from the input parameters.
    EntityReference entity = (EntityReference)context.InputParameters["Target"];

Once you have access to the entity data, you can read and modify it. Any data changes to the context performed by plug-ins registered in stage 10 or 20 of the pipeline are passed in the context to the core operation in stage 30.


Not all fields in an entity record that are passed to a plug-in through the context can be modified. You should check the field’s IsValidForUpdate metadata property to verify that it isn’t set to false. Attempting to change the value of a field that can’t be updated results in an exception.

Similarly, the OutputParameters property contains the data that is in the response message, for example CreateResponse, currently being passed through the event execution pipeline. However, only synchronous post-event and asynchronous registered plug-ins have OutputParameters populated as the response is the result of the core platform operation. The property is of type ParameterCollection where the keys to access the response data are the names of the actual public properties in the response.

PreEntityImages and PostEntityImages contain snapshots of the primary entity's attributes before (pre) and after (post) the core platform operation. 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. 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.

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. In addition, only a small subset of messages support pre and post images as shown in the following table.

Message Request





The assigned entity.



The created entity.



The deleted entity.



The delivered email ID.



The delivered email ID.



The workflow entity.



The parent entity, into which the data from the child entity is being merged.



The child entity that is being merged into the parent entity.



The sent entity ID.



The entity for which the state is set.



The updated entity.

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.

System_CAPS_security Security Note

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. More information: Impersonation in plug-ins

Microsoft Dynamics 365

© 2016 Microsoft. All rights reserved. Copyright