Answered by:
CRM 2011 - Async Plugin for Delete Message Uses System User context

Question
-
I have an asynchronous plugin step registered for a custom entity on the delete message. The step is registered to use the calling user’s context but when the step is executed the system user is used. This is causing validation errors when the plugin step tries to do its job.
Is it expected that a async plugin for the delete message will use the system user and not the calling user?
The plugin registration is:
Isolation Mode – Sandbox
Assembly location – Database
Message – Delete
Primary Entity – rasv_privilegeday
Secondary Entity – none
Run in User’s Context – Calling User
Execution Order – 1
Pipeline Stage – Post-operation
Execution Mode – Asynchronous
Deployment - Server
Thanks.
Tim.Tuesday, July 19, 2011 5:46 AM
Answers
-
Hi,
Try like this:
// Obtain the execution context from the service provider. Microsoft.Xrm.Sdk.IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); OrganizationServiceFactory wod_serviceFactory = null; IOrganizationService wod_CrmService = null; // Obtain the service factory to get the service object wod_serviceFactory = (IOrganizationServiceFactory)serviceProvider .GetService(typeof(IOrganizationServiceFactory)); // Obtain service object Imporsonated as plugin calling user <strong>wod_CrmService = wod_serviceFactory.CreateOrganizationService(context.InitiatingUserId); </strong>
Jehanzeb Javeed
http://worldofdynamics.blogspot.com
Linked-In Profile |CodePlex Profile
If you find this post helpful then please "Vote as Helpful" and "Mark As Answer".- Marked as answer by Tim McColl Tuesday, July 19, 2011 10:10 AM
Tuesday, July 19, 2011 7:38 AM
All replies
-
I guess it could be the way you have created the IOrganizationService (service) class using CreateOrganizationService method
IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory)); IOrganizationService service = factory.CreateOrganizationService(context.UserId);
Thomas T(MCBMSS)- Proposed as answer by Thomas Thankachan Tuesday, July 19, 2011 7:07 AM
Tuesday, July 19, 2011 6:43 AM -
Hi,
You have to also set the Run in Context User in Plugin step registraiton. For complete details on Imporsonation in plugins you may refer: http://msdn.microsoft.com/en-us/library/gg309416.aspx
Jehanzeb Javeed
http://worldofdynamics.blogspot.com
Linked-In Profile |CodePlex Profile
If you find this post helpful then please "Vote as Helpful" and "Mark As Answer".- Proposed as answer by Jehanzeb.Javeed Tuesday, July 19, 2011 7:00 AM
- Unproposed as answer by Jehanzeb.Javeed Tuesday, July 19, 2011 7:40 AM
Tuesday, July 19, 2011 7:00 AM -
The plugin step is registered with ImpersonatingUserId set to null using the SDK Plugin Registration Tool. So I’m expecting the user context of the plugin step to be the initiating user and not the “system” user. The delete plugin step is being initiated by the delete ribbon bottom on the entities form. The other plugin steps (create/update) that are also async run in the context of the initiating user. It’s just the delete step that has the “system” user context.
From the SDK doco at http://msdn.microsoft.com/en-us/library/gg309416.aspx
“Whether the calling/logged on user or "system" user is used for impersonation is dependent on the request being processed by the pipeline and is beyond the scope of the SDK documentation. For more information aboutthe "system" user, refer to the next topic.”
Is an async delete step one of those “beyond scope of the SDK”?
Tuesday, July 19, 2011 7:26 AM -
Hi,
Try like this:
// Obtain the execution context from the service provider. Microsoft.Xrm.Sdk.IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext)); OrganizationServiceFactory wod_serviceFactory = null; IOrganizationService wod_CrmService = null; // Obtain the service factory to get the service object wod_serviceFactory = (IOrganizationServiceFactory)serviceProvider .GetService(typeof(IOrganizationServiceFactory)); // Obtain service object Imporsonated as plugin calling user <strong>wod_CrmService = wod_serviceFactory.CreateOrganizationService(context.InitiatingUserId); </strong>
Jehanzeb Javeed
http://worldofdynamics.blogspot.com
Linked-In Profile |CodePlex Profile
If you find this post helpful then please "Vote as Helpful" and "Mark As Answer".- Marked as answer by Tim McColl Tuesday, July 19, 2011 10:10 AM
Tuesday, July 19, 2011 7:38 AM -
Thanks that got me thinking in the right direction. I was using IPluginExecutionContext.UserId instead of IPluginExecutionContext.InitiatingUserId. The async delete step is the first time I’ve seen these two properties different. Usually they are both the Id of the initiating user. But for the async delete step UserId is the “system” user and only InitiatingUserId is the initiating user.
I remember when I first read the SDK for UserId and InitiatingUserId I couldn’t tell what the difference was.
“InitiatingUserId - Gets the global unique identifier of the system user account under which the current pipeline is executing.”
“UserId - Gets the global unique identifier of the system user for whom the plug-in invokes Web service methods on behalf of.”Tuesday, July 19, 2011 10:09 AM -
This got a bit more complicated than I first thought. For a normal synchronous plugin step both InitiatingUserId and UserId are the guid of the real user clicking the save button. For plugin steps registered for a specific context user, InitiatingUserId is the real user and UserId is the context user. For async create and update steps InitiatingUserId and UserId are both the real user. But async delete steps have UserId as the “system” user and InitiatingUserId is the readl user.
Wednesday, July 20, 2011 12:27 PM