{"id":1223,"date":"2011-01-06T20:33:04","date_gmt":"2011-01-06T20:33:04","guid":{"rendered":"https:\/\/www.wapshere.com\/missmiis\/?p=1223"},"modified":"2011-03-09T07:56:32","modified_gmt":"2011-03-09T07:56:32","slug":"passing-data-from-a-custom-workflow-via-the-request-object","status":"publish","type":"post","link":"https:\/\/www.wapshere.com\/missmiis\/passing-data-from-a-custom-workflow-via-the-request-object","title":{"rendered":"Passing data from a custom Workflow via the Request object"},"content":{"rendered":"<p><a href=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-02-MPR-allowing-request-creators-to-read-new-attribs.jpg\"><\/a>I have been writing an activity that resets forgotten BPOS passwords (more on that later) and I wanted to include a Notification activity that would inform the user about the password reset request. To make the notification useful I want to include whether the reset succeeded, and if it failed, what the reason was. To do this I need to be able to pass information from the custom &#8220;Change BPOS Password&#8221;\u00c2\u00a0activity to the Notification activity.<\/p>\n<p><a href=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-07-workflow-notif-detail1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1226\" title=\"pass 07 workflow - notif detail\" src=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-07-workflow-notif-detail1.jpg\" alt=\"\" width=\"736\" height=\"323\" srcset=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-07-workflow-notif-detail1.jpg 736w, https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-07-workflow-notif-detail1-300x131.jpg 300w\" sizes=\"auto, (max-width: 736px) 100vw, 736px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-07-workflow-notif-detail.jpg\"><\/a><br \/>\n<!--more--><\/p>\n<h3>What does the documentation say?<\/h3>\n<p>The first thing I did was consult the official document <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ff463694.aspx\">Developing Custom Activities and Workflows<\/a>.\u00c2\u00a0The only\u00c2\u00a0thing I could find about passing data\u00c2\u00a0was this:<\/p>\n<blockquote>\n<h3>Passing Data between Workflow Phases<\/h3>\n<div>\n<p>Some scenarios may require that an authorization workflow share some information with an action workflow that runs for the same request. (For more information, see <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ee652475.aspx\">Request Processing<\/a>.) The recommended approach for accomplishing this scenario is as follows:<\/p>\n<h4>Passing Data from an Authorization Workflow Activity to an Action Workflow<\/h4>\n<ol>\n<li>Create and bind one or more attributes to the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ee652273.aspx\">Request<\/a> resource type in the FIM schema that can store the information that you want to share between activities. You can do this through Web services or by using the FIM Portal.<\/li>\n<li>Grant permissions to the person or resource that will be assigned to the <strong>ActorID<\/strong> of the activity to read and modify the new attribute. Note that this step is not required if the <strong>ActorID<\/strong> is set to the FIM Service Account resource. For more information, see <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/microsoft.resourcemanagement.workflow.activities.aspx\">Microsoft.ResourceManagement.Workflow.Activities<\/a>.<\/li>\n<li>In the authorization workflow activity, use the <strong>UpdateResourceActivity<\/strong> activity to set the desired value on the new attribute.<\/li>\n<li>In the action workflow activity, use the <strong>ReadResourceActivity<\/strong> to get the value of the new attribute.<\/li>\n<\/ol>\n<\/div>\n<\/blockquote>\n<p>However this didn&#8217;t seem to address my simpler situation. I&#8217;m not trying to pass a value between an AuthZ and an Action workflow &#8211; I just want to pass the data between two steps in the same Action workflow. Perhaps I can use a WorkflowData parameter?<\/p>\n<p>But as I thought about it I decided that maybe the method mentioned in the documentation was the right way to go. Essentially I am updating the request object itself with the results of the activity, and this then forms a permanent record. To jump ahead in the story, here&#8217;s what a request object looks like after a failed password reset operation. I think that&#8217;s pretty useful!<\/p>\n<p><a href=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-11-failed-request.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1228\" title=\"pass 11 failed request\" src=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-11-failed-request.jpg\" alt=\"\" width=\"618\" height=\"233\" srcset=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-11-failed-request.jpg 773w, https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-11-failed-request-300x112.jpg 300w\" sizes=\"auto, (max-width: 618px) 100vw, 618px\" \/><\/a><\/p>\n<h3>Create the Attributes<\/h3>\n<p>So following step one from the documentation, I created the following attributes and bound them to the Request resource type:<\/p>\n<ul>\n<li>&#8220;Activity Status&#8221; &#8211; indexed string. This will normally contain &#8220;Succeeded&#8221; or &#8220;Failed&#8221;.<\/li>\n<li>&#8220;Activity Status Message&#8221; &#8211; unindexed string. Here I can put extra info about why an activity failed.<\/li>\n<\/ul>\n<p><a href=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-011.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1233\" title=\"pass 01\" src=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-011.jpg\" alt=\"\" width=\"632\" height=\"161\" srcset=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-011.jpg 702w, https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-011-300x76.jpg 300w\" sizes=\"auto, (max-width: 632px) 100vw, 632px\" \/><\/a><\/p>\n<h3>Grant\u00c2\u00a0permissions to the new attributes<\/h3>\n<p>I added the new attributes to both of the following MPRs:\u00c2\u00a0 <strong>Request management: Request creators can read their approval resources<\/strong> and <strong>Request management: Request participants can read their request resources<\/strong>.<\/p>\n<p><a href=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-02-MPR-allowing-request-creators-to-read-new-attribs.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1235\" title=\"pass 02 MPR allowing request creators to read new attribs\" src=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-02-MPR-allowing-request-creators-to-read-new-attribs.jpg\" alt=\"\" width=\"634\" height=\"306\" srcset=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-02-MPR-allowing-request-creators-to-read-new-attribs.jpg 704w, https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-02-MPR-allowing-request-creators-to-read-new-attribs-300x144.jpg 300w\" sizes=\"auto, (max-width: 634px) 100vw, 634px\" \/><\/a><\/p>\n<p>I also updated <strong>Administration: Administrators can control requests <\/strong>because I&#8217;m using the FIM service account to make the changes to the request (note the documentation above says you don&#8217;t have to do that if using the service account . I think that may be a mistake as rights always have to be granted, and I certainly had to).<\/p>\n<p><a href=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-04-MPR-allowing-admin-to-update-new-attribs1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1236\" title=\"pass 04 MPR allowing admin to update new attribs\" src=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-04-MPR-allowing-admin-to-update-new-attribs1.jpg\" alt=\"\" width=\"644\" height=\"388\" srcset=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-04-MPR-allowing-admin-to-update-new-attribs1.jpg 716w, https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-04-MPR-allowing-admin-to-update-new-attribs1-300x180.jpg 300w\" sizes=\"auto, (max-width: 644px) 100vw, 644px\" \/><\/a><\/p>\n<h3>Code the custom workflow activity to update the Request<\/h3>\n<p>&nbsp;<\/p>\n<table border=0>\n<tbody>\n<tr>\n<td width=156><a href=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-vb-workflow1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1238\" title=\"pass vb workflow\" src=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-vb-workflow1.jpg\" alt=\"\" width=\"146\" height=\"274\" \/><\/a><\/td>\n<td>The custom workflow must include a CurrentRequestActivity to get the details of the current request &#8211; I think this is probably standard anyway.<\/p>\n<p>Here I&#8217;m finishing up with two UpdateResourceActivities which update respectively the &#8220;Activity Status&#8221; and &#8220;Activity Status Message&#8221;.<\/p>\n<p>And I also need a code activity somewhere to feed the values to the UpdateResourceActivities. I tack this at the end of the code activity where I&#8217;m running my password reset code, because that&#8217;s where I have easy access to the results of the reset attempt. This code that sets up the UpdateResourceActivities is below. Note I am using the Built-In Admin account to update the request object. The variable &#8220;failureMessage&#8221; was already set earlier in the code.\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p><code><\/p>\n<pre>\r\n    Const FIMADMIN_GUID As String = \"7fb2b853-24f0-4498-9534-4e10589723c4\"\r\n\r\n    '' Prepare variables for UpdateRequest activities which write the activity status back to the Request object.\r\n    Me.updateRequest1_ActorId1 = New Guid(FIMADMIN_GUID)\r\n    Me.updateRequest1_ResourceId1 = Me.currentRequestActivity1.CurrentRequest.ObjectID\r\n    Dim updateInstruction1 As New UpdateRequestParameter\r\n    updateInstruction1.PropertyName = \"ActivityStatus\"\r\n    If success Then\r\n        updateInstruction1.Mode = UpdateMode.Modify\r\n        updateInstruction1.Value = \"Succeeded\"\r\n    Else\r\n        updateInstruction1.Mode = UpdateMode.Modify\r\n        updateInstruction1.Value = \"Failed\"\r\n    End If\r\n\r\n    Me.updateRequest1_UpdateParameters1 = New UpdateRequestParameter() {updateInstruction1}\r\n    Me.updateRequest2_ActorId1 = New Guid(FIMADMIN_GUID)\r\n    Me.updateRequest2_ResourceId1 = Me.currentRequestActivity1.CurrentRequest.ObjectID\r\n    Dim updateInstruction2 As New UpdateRequestParameter\r\n    updateInstruction2.PropertyName = \"ActivityStatusMessage\"\r\n    If success Then\r\n        'No message\r\n    Else\r\n        updateInstruction2.Mode = UpdateMode.Modify\r\n        updateInstruction2.Value = failureMessage\r\n    End If\r\n    Me.updateRequest2_UpdateParameters1 = New UpdateRequestParameter() {updateInstruction2}\r\n<\/pre>\n<p><\/code><\/p>\n<h3>Accessing the values from an Email Template<\/h3>\n<p>My final step is to create the Email Template that will be used by the Notification Activity.<\/p>\n<p>For the Subject:<br \/>\n<code><\/p>\n<pre>BPOS Password Reset [\/\/Request\/ActivityStatus]<\/pre>\n<p><\/code><\/p>\n<p>And in the body I add the following:<br \/>\n<code><\/p>\n<pre>&lt;p class=\"MsoNormal\"&gt;&lt;b&gt;Request Status:&lt;\/b&gt;&lt;\/p&gt;\r\n&lt;p class=\"MsoNormal\"&gt;[\/\/Request\/ActivityStatus]&lt;\/p&gt;\r\n&lt;p class=\"MsoNormal\"&gt;[\/\/Request\/ActivityStatusMessage]&lt;\/p&gt;\r\n&lt;p class=\"MsoNormal\"&gt;&lt;o:p&gt;&nbsp;&lt;\/o:p&gt;&lt;\/p&gt;<\/pre>\n<p><\/code><\/p>\n<p>The result is that the password reset operation runs and depending on the result of the attempt, the user gets one of these emails:<\/p>\n<p><a href=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-12-email-1.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-12-email-1.jpg\" alt=\"\" title=\"pass 12 email 1\" width=\"460\" height=\"295\" class=\"alignnone size-full wp-image-1244\" srcset=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-12-email-1.jpg 460w, https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-12-email-1-300x192.jpg 300w\" sizes=\"auto, (max-width: 460px) 100vw, 460px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-12-email-2.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-12-email-2.jpg\" alt=\"\" title=\"pass 12 email 2\" width=\"527\" height=\"350\" class=\"alignnone size-full wp-image-1245\" srcset=\"https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-12-email-2.jpg 527w, https:\/\/www.wapshere.com\/missmiis\/wp-content\/uploads\/2011\/01\/pass-12-email-2-300x199.jpg 300w\" sizes=\"auto, (max-width: 527px) 100vw, 527px\" \/><\/a><\/p>\n<p>And I think that that&#8217;s pretty cool!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I have been writing an activity that resets forgotten BPOS passwords (more on that later) and I wanted to include a Notification activity that would inform the user about the password reset request. To make the notification useful I want to include whether the reset succeeded, and if it failed, what the reason was. To&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":[]},"categories":[52,42,30,45],"tags":[],"class_list":["post-1223","post","type-post","status-publish","format-standard","hentry","category-email-template","category-fim-2010","category-vbnet","category-workflow"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/pkp1o-jJ","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/posts\/1223","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/comments?post=1223"}],"version-history":[{"count":17,"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/posts\/1223\/revisions"}],"predecessor-version":[{"id":1255,"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/posts\/1223\/revisions\/1255"}],"wp:attachment":[{"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/media?parent=1223"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/categories?post=1223"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wapshere.com\/missmiis\/wp-json\/wp\/v2\/tags?post=1223"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}