Add users to Sharepoint 2010 approval workflow using c#

I am trying to start a standard Sharepoint 2010 approval workflow using c#. Currently I’m facing difficulties in adding or updating approvers/ users programmatically for the highlighted fields in the initiation form, as shown in the screenshot below. Since no users are added, no tasks are assigned and the workflow is rejected.

enter image description here

The following is the code that I use to start the workflow (based on this blog post: Start a SharePoint 2010 List Workflow with CSOM):

using Microsoft.SharePoint.Client; using Microsoft.SharePoint.Client.Workflow; using Microsoft.SharePoint.Client.WorkflowServices; … …  string SharepointURL = "https://testSharepointSite.com/sites/Test";  //Name of the List to which the Workflow is Associated string targetListName = "Documents";  //connect to Sharepoint URL with Windows Credentials ClientContext clientContext = new ClientContext(SharepointURL); List list = clientContext.Web.Lists.GetByTitle(targetListName);  // load list clientContext.Load(list); clientContext.Load(list.Fields); clientContext.ExecuteQuery();  // get list item (a document in sharepoint to approve) ListItem item = list.GetItemById("17");  // load item clientContext.Load(item); clientContext.ExecuteQuery();  // Name of approval workflow string workflowName = "ApprovalProcessTest";  Web web = context.Web;  // Guid of the List to which the Workflow is Associated Guid targetListGUID = new Guid("b89e266c-5f20-4b83-9f95-10a42c629e84");  // GUID of list item (DPM file) on which to start the workflows Guid itemGuid = (Guid)item.FieldValues["GUID"];  // Workflow Services Manager which will handle all the workflow interaction  WorkflowServicesManager workflowServicesManager = new WorkflowServicesManager(context, web);  // Return all Workflow Associations which are running on the SharePoint 2010 Engine WorkflowAssociationCollection workflowAssociations = list.WorkflowAssociations; context.Load(workflowAssociations); context.ExecuteQuery();  // Get the required Workflow Association WorkflowAssociation workflowAssociation = workflowAssociations.GetByName(workflowName); context.Load(workflowAssociation); context.ExecuteQuery();  // Get the instance of the Interop Service which will be used to create an instance of the Workflow InteropService workflowInteropService = workflowServicesManager.GetWorkflowInteropService();  // Start the Workflow ClientResult<Guid> resultGuid = workflowInteropService.StartWorkflow(         workflowAssociation.Name,         new Guid(),          targetListGUID,          itemGuid,          SharePointListItem_RW // <- dictionary<string, object> to pass initiation data/ workflow parameters       );  context.ExecuteQuery(); 

As you can see in the very last part of the code, I can use a dictionary to pass initiation data to the form above. I’ve looked in the association data of the workflow to get an idea of how the dictionary should look like. Following is the XML of the association data that I get from workflowAssociation.AssociationData:

<dfs:myFields xmlns:d="http://schemas.microsoft.com/office/infopath/2009/WSSList/dataFields"     xmlns:dfs="http://schemas.microsoft.com/office/infopath/2003/dataFormSolution"      xmlns:dms="http://schemas.microsoft.com/office/2009/documentManagement/types"      xmlns:ma="http://schemas.microsoft.com/office/2009/metadata/properties/metaAttributes"              xmlns:pc="http://schemas.microsoft.com/office/infopath/2007/PartnerControls"              xmlns:q="http://schemas.microsoft.com/office/infopath/2009/WSSList/queryFields"              xmlns:xsd="http://www.w3.org/2001/XMLSchema"              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">     <dfs:queryFields/>     <dfs:dataFields>         <d:SharePointListItem_RW>             <d:Approvers>                 <d:Assignment>                     <d:Assignee>                         <pc:Person>                             <pc:DisplayName>User Name</pc:DisplayName>                             <pc:AccountId>domain\user</pc:AccountId>                             <pc:AccountType>User</pc:AccountType>                         </pc:Person>                         <pc:Person>                             <pc:DisplayName>User name2</pc:DisplayName>                             <pc:AccountId>domain\user2</pc:AccountId>                             <pc:AccountType>User</pc:AccountType>                         </pc:Person>                     </d:Assignee>                     <d:Stage xsi:nil="true"/>                     <d:AssignmentType>Serial</d:AssignmentType>                 </d:Assignment>             </d:Approvers>             <d:ExpandGroups>true</d:ExpandGroups>             <d:NotificationMessage>A comment</d:NotificationMessage>             <d:DueDateforAllTasks>2019-09-29T22:00:00.0000000Z</d:DueDateforAllTasks>             <d:DurationforSerialTasks>2</d:DurationforSerialTasks>             <d:CC>                 <pc:Person>                     <pc:DisplayName>User name</pc:DisplayName>                     <pc:AccountId>domain\user</pc:AccountId>                     <pc:AccountType>User</pc:AccountType>                 </pc:Person>             </d:CC>             <d:CancelonRejection>false</d:CancelonRejection>             <d:CancelonChange>false</d:CancelonChange>             <d:EnableContentApproval>false</d:EnableContentApproval>         </d:SharePointListItem_RW>     </dfs:dataFields> </dfs:myFields> 

Based on the XML, I created the following dictionary:

User user = web.EnsureUser(@"domain\user"); context.Load(user); context.ExecuteQuery();  // does not work Dictionary<string, object> Person = new Dictionary<string, object>(); Person["DisplayName"] = user.Title; Person["AccountId"] = user.LoginName;  Person["AccountType"] = "User";  // does not work Dictionary<string, object> Assignment = new Dictionary<string, object>(); Assignment["Assignee"] = assignee; Assignment["AssignmentType"] = "Serial";  // does not work Dictionary<string, object> Approvers = new Dictionary<string, object>(); Approvers["Assignment"] = Assignment;  Dictionary<string, object> SharePointListItem_RW = new Dictionary<string, object>(); SharePointListItem_RW["Approvers"] = Approvers; // does not work SharePointListItem_RW["NotificationMessage"] = "Lorem Ipsum v3"; // works SharePointListItem_RW["DueDateforAllTasks"] = "2019-09-25"; // works SharePointListItem_RW["DurationforSerialTasks"] = 2; // no idea, cannot test SharePointListItem_RW["DurationUnits"] = "Days"; // no idea, cannot test  // does not work Dictionary<string, object> cc = new Dictionary<string, object>(); cc["Person"] = Person; SharePointListItem_RW["CC"] = cc; 

Using the dictionary, I can pass a comment and the due date, but not the users for approval and cc.

I’ve been stuck on this problem now for a couple of days. Googling around did not return any positive results. The above codes are the last that I tried.

Any ideas now on how can I add one or more users in the dictionary?