Answered by:
Get record GUID created by workflow in plugin

Question
-
Hi,
I wonder if there's any possibility to get entities / entity guids created by workflow started from plugin?
I tried to get some data from ExecuteWorkflowResponse with no luck
Thanks in advance!
- Edited by MervinHut Tuesday, December 18, 2012 5:59 PM
- Changed type JLattimerMVP, Moderator Tuesday, December 18, 2012 6:00 PM
Tuesday, December 18, 2012 5:58 PM
Answers
-
As has been alluded to, you cannot wait for the completion of a Workflow from within the execution of a synchronous plugin. Synchronous plugins terminate after 2:00mins; you cannot rely on a Workflow to trigger and complete within 2 minutes.
As has also been suggested, you can run your plugin asynchronously; this will allow you to execute long running operations, however your plugin will no longer execute in "real time".
If you decide to stick with the Workflow polling mechanism or wish to do so in future, the ExecuteWorkflowResponse returns an AsyncOperationId. To determine the outcome of that operation, you must periodically poll the CRM system in a loop until the operation has completed or failed:
ExecuteWorkflowRequest req = new ExecuteWorkflowRequest(); req.EntityId = contact.Id; req.WorkflowId = new Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"); ExecuteWorkflowResponse resp = (ExecuteWorkflowResponse)xrm.Execute(req); Guid asyncOperationId = resp.Id; QueryByAttribute retrieveOpQuery = new QueryByAttribute { EntityName = "asyncoperation", ColumnSet = new ColumnSet("statecode") }; retrieveOpQuery.AddAttributeValue("asyncoperationid", asyncOperationId); // Wait for the asyncoperation to complete. // (wait no longer than 1 minute) for (int i = 0; i < 60; i++) { System.Threading.Thread.Sleep(1000); EntityCollection retrieveOpResults = xrm.RetrieveMultiple(retrieveOpQuery); if (retrieveOpResults.Entities.Count() > 0) { Entity op = retrieveOpResults.Entities[0]; if (((OptionSetValue)op["statecode"]).Value == 3 /* Completed */) { // success !! break; } } if (i == 59) { // timeout } }
All that said, I would try to simplify the architecture. Spawning and waiting on Workflows makes it unclear what is occurring when someone has to debug and/or modify the process at a later date. Consider any of the following:
- If you MUST run the operation in real time, you cannot rely on Workflow to implement any of the functionality. Move all logic it into your plugin
- If asynchronous operation is OK, move your plugin logic into a Custom Workflow Activity (assuming the message on which your plugin triggers can be triggered via Workflow)
--pogo (pat) @ pogo69.wordpress.com
- Proposed as answer by HIMBAPModerator Wednesday, December 19, 2012 4:49 AM
- Marked as answer by MervinHut Wednesday, December 19, 2012 4:57 PM
Wednesday, December 19, 2012 1:08 AM
All replies
-
Hi,
To clear up your requirement: You create a new record in a workflow and want to get the guid of the created record for other purposes - right?!
Best regards,
Andreas
Andreas Buchinger
Microsoft Dynamics Certified Technology Specialist
MCPD: SharePoint Developer 2010Tuesday, December 18, 2012 7:25 PM -
Hi,
Yes, that's correct. Please note that I run workflow inside a plugin and I want to get the created entity there after the workflow is executed.
Tuesday, December 18, 2012 8:30 PM -
Hi,
Can you please explain to me how you run a workflow inside of a plugin - I don't understand that point!?
br,
Andreas
Andreas Buchinger
Microsoft Dynamics Certified Technology Specialist
MCPD: SharePoint Developer 2010Tuesday, December 18, 2012 8:53 PM -
Andreas,
Here's the code:
ExecuteWorkflowRequest request = new ExecuteWorkflowRequest() { WorkflowId = new Guid("3D007B8A-B73B-440F-A862-23C5D4422336"), EntityId = new Guid("41E4BAD8-3649-E211-A71D-0050562355CE") }; ExecuteWorkflowResponse response = (ExecuteWorkflowResponse) pluginContext.OrganizationService.Execute(request);
ExecuteWorkflowResponse contains async operation id (since workflow is performed in async manner) but I'm not sure if we can get anything useful from this ID somehow
Tuesday, December 18, 2012 9:03 PM -
Hi,
OK - it's clear...
I think it's not possible to "wait" for the workflow response because the workflow runs async - so the execution could be some time later. Why don't you execute the steps after the workflow call inside of the called workflow. In my opinion this is the only chance to get the id of the created record.
br,
Andreas
Andreas Buchinger
Microsoft Dynamics Certified Technology Specialist
MCPD: SharePoint Developer 2010Tuesday, December 18, 2012 9:10 PM -
Andreas,
Thanks for your answer.
Do you mean execute steps right in the plugin? If yes, could you please shed some light on how this can be done ?
- Edited by MervinHut Tuesday, December 18, 2012 9:15 PM
Tuesday, December 18, 2012 9:15 PM -
Hi MervinHut,
I think what Andreas meant was that workflow call should be the last step in your plugin and you shouldn't come back to plugin after you make a workflow call. Instead of coming back to the Plugin, perform all the remaining tasks in your workflow which was called from plugin by adding some additional steps to your workflow. It makes absolute sense but it all depends what are those steps that you are performing in plugin after you make a workflow call. Can they be achieved using a workflow? If yes, then your issue is resolved, otherwise, try to run your plugin in 'Async' mode. It might resolve your issue.
If this post answers your question, please click "Mark As Answer" on the post and "Mark as Helpful" Thanks, Imran Abbasi
Wednesday, December 19, 2012 12:05 AM -
As has been alluded to, you cannot wait for the completion of a Workflow from within the execution of a synchronous plugin. Synchronous plugins terminate after 2:00mins; you cannot rely on a Workflow to trigger and complete within 2 minutes.
As has also been suggested, you can run your plugin asynchronously; this will allow you to execute long running operations, however your plugin will no longer execute in "real time".
If you decide to stick with the Workflow polling mechanism or wish to do so in future, the ExecuteWorkflowResponse returns an AsyncOperationId. To determine the outcome of that operation, you must periodically poll the CRM system in a loop until the operation has completed or failed:
ExecuteWorkflowRequest req = new ExecuteWorkflowRequest(); req.EntityId = contact.Id; req.WorkflowId = new Guid("xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"); ExecuteWorkflowResponse resp = (ExecuteWorkflowResponse)xrm.Execute(req); Guid asyncOperationId = resp.Id; QueryByAttribute retrieveOpQuery = new QueryByAttribute { EntityName = "asyncoperation", ColumnSet = new ColumnSet("statecode") }; retrieveOpQuery.AddAttributeValue("asyncoperationid", asyncOperationId); // Wait for the asyncoperation to complete. // (wait no longer than 1 minute) for (int i = 0; i < 60; i++) { System.Threading.Thread.Sleep(1000); EntityCollection retrieveOpResults = xrm.RetrieveMultiple(retrieveOpQuery); if (retrieveOpResults.Entities.Count() > 0) { Entity op = retrieveOpResults.Entities[0]; if (((OptionSetValue)op["statecode"]).Value == 3 /* Completed */) { // success !! break; } } if (i == 59) { // timeout } }
All that said, I would try to simplify the architecture. Spawning and waiting on Workflows makes it unclear what is occurring when someone has to debug and/or modify the process at a later date. Consider any of the following:
- If you MUST run the operation in real time, you cannot rely on Workflow to implement any of the functionality. Move all logic it into your plugin
- If asynchronous operation is OK, move your plugin logic into a Custom Workflow Activity (assuming the message on which your plugin triggers can be triggered via Workflow)
--pogo (pat) @ pogo69.wordpress.com
- Proposed as answer by HIMBAPModerator Wednesday, December 19, 2012 4:49 AM
- Marked as answer by MervinHut Wednesday, December 19, 2012 4:57 PM
Wednesday, December 19, 2012 1:08 AM -
Thanks all of you for your help!
I think I need to rethink the whole approach not to use workflows in such way!
Wednesday, December 19, 2012 5:18 PM