How to change a Plugin “Run in User’s Context” Programmatically

When you design Plugins for Microsoft Dynamics CRM, you sometime need to have them run as a different user in order to perform operations that a non admin user cannot normally do. This is usually done by using the Plugin Registration tool and setting the value of the “Run in User’s Context” drop down field to a specific value (see screenshot below).

Today I want to show a way to do this programmatically. Our design is fairly simple and the overall goal is to have the appropriate impersonation user being assigned to all required plugin steps automatically without manual processing post-solution import.

  • Create Plugins and steps with the Plugin Registration Tool as usual
  • The name of each plugin that requires to run as an admin user must contain a pre-defined text (in our case [Admin])
  • After each solution is imported to CRM, a plugin fires and look for all plugin steps where the name contains [Admin]
  • Updated the Run In User’s Context field with an admin user defined as per configuration

That’s easy enough. For step 4, where you store the configuration is up to you, it could be registry, XML web resource, custom entity etc.

Here is the code to do it:

Cheers

Run multiple requests with one service call using ExecuteMultipleRequest

If you have been developing on for Dynamics CRM for a while, you probably asked yourself this question at least one: why is there not a way to send multiple service requests with a single call to the organization service. It’s finally here. It was introduced with UR12 on CRM 2011 and is of course available for CRM 2013. The request type is ExecuteMultipleRequest. It’s really simple to use. Here are the steps and code snippet below:

  • Create a collection of entity records you need to action on (create or update or delete)
  • Create the ExecuteMultipleRequest object and add the settings:
    • ContinueOnError
    • ReturnResponse
  • Add a request for each entity to the request collection
  • Call the IOrganizationService Execute method and passing the ExecuteMultipleRequest object in parameter
public void ExecutePluginOperation(LocalPluginContext obj)
{
IOrganizationService service = obj.OrganizationService;
IExecutionContext context = obj.PluginExecutionContext;

Incident incident = (context.InputParameters["Target"] as Entity).ToEntity<Incident>();
EntityCollection entitesToCreate = GetEntitiesToCreate(incident);

ExecuteMultipleRequest requestWithResults = new ExecuteMultipleRequest()
{
// Assign settings that define execution behavior
Settings = new ExecuteMultipleSettings()
{
ContinueOnError = true,
ReturnResponses = true
},
// Create an empty organization request collection.
Requests = new OrganizationRequestCollection()
};

// Add a CreateRequest for each entity to the request collection.
foreach (var entity in entitesToCreate.Entities)
{
if (entity.Id == Guid.Empty)
{
CreateRequest createRequest = new CreateRequest { Target = entity };
requestWithResults.Requests.Add(createRequest);
}
else
{
UpdateRequest createRequest = new UpdateRequest { Target = entity };
requestWithResults.Requests.Add(createRequest);
}            }

// Execute all the requests in the request collection using a single web method call.
ExecuteMultipleResponse responseWithResults = (ExecuteMultipleResponse)service.Execute(requestWithResults);
}

Notes:

  • You can only make multiple requests that make changes or create entities of different types (e.g. Contacts, Accounts)
  • You can make multiple requests of different types (create, updates and delete requests in a single call)

It’s a very nice performance optimization in certain scenarios!