Workflow REST API: Open and Complete Task

This sample shows how to open a specific task and complete the task with a specific task action. Note the use of DataContract classes to serialize the task.

//use a System.Net.Http.HttpClient to send the request.
//TODO: You will have to construct the HttpClient and authentication for the webclient before running the snippet
System.Net.Http.HttpClient k2WebClient;

//the unique serial number of the task you want to open and action
string taskSerialNumber = "1_1";

//construct the endpoint for the task operation (requires the task serial number). Your URL will likely be different.
string operationEndPoint = @ "https://k2.denallix.com/api/workflow/v1/tasks/" + taskSerialNumber;

string responseBody = k2WebClient.GetStringAsync(operationEndPoint).Result;

//read in the task using a serializer
WorkflowRestAPISamples.Tasks_TaskContract.K2Task task = new WorkflowRestAPISamples.Tasks_TaskContract.K2Task();

using (System.IO.MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(responseBody))) {
 DataContractJsonSerializer ser = new DataContractJsonSerializer(task.GetType());
 task = ser.ReadObject(ms) as WorkflowRestAPISamples.Tasks_TaskContract.K2Task;
}

//Do something with the task/workflow instance information
Console.WriteLine("Workflow Name" + task.WorkflowName);
Console.WriteLine("Activity Name: " + task.ActivityName);
Console.WriteLine("Folio: " + task.WorkflowInstanceFolio);
Console.WriteLine("Available Actions: ");
foreach (string systemAction in task.Actions.SystemActions) {
 Console.WriteLine("System Action: " + systemAction);
}
foreach (string batchAction in task.Actions.BatchableActions) {
 Console.WriteLine("Batchable Action: " + batchAction);
}
foreach (string nonbatchAction in task.Actions.NonBatchableActions) {
 Console.WriteLine("Non-Batchable Action: " + nonbatchAction);
}

//actioning/completing the task
//determine the action to take on the task (read the available actions from the task.Actions collections)
string actionName = "Approve";
string actionEndpointURI = TasksEndpointURI + @ "/" + taskSerialNumber + @ "/actions/" + actionName;
//if you want to update workflow datafields/variables when completing the task,
//ou need to define the datafields and serialize them as a JSON string.
//Either hardcode the string as in this example, or create your own DataContract class and serialize it
//example using a constructed string
//string datafieldsToUpdateJSON = "{\"dataFields\":{\"TextVariable\": \"newValueForTextVariable\"}}";
//if you are not setting any datafield values, set the datafieldsToUpdateJSON to an empty value like this:
//string datafieldsToUpdateJSON = "{}";

//example using a data contract and serialization, in this case the class is defined specifically for the workflow
//definition we're working with
Tasks_TaskContract.WorkflowInstanceDataFields wfDatafields = new Tasks_TaskContract.WorkflowInstanceDataFields();
wfDatafields.TextVariable = "newStringValue";
wfDatafields.DecimalVariable = (long) 999.99;
wfDatafields.NumberVariable = 99;

//serialize the datafields to JSON format and read it in
DataContractJsonSerializer ser1 = new DataContractJsonSerializer(wfDatafields.GetType());
System.IO.MemoryStream ms1 = new System.IO.MemoryStream();
ser1.WriteObject(ms1, wfDatafields);

string encodedJsonObject = Encoding.UTF8.GetString(ms1.ToArray());
//NOTE: if your datafield names have spaces, you may need to edit the serialized string to add the spaces back in.
//e.g. encodedJsonObject = encodedJsonObject.Replace("TextDatafield", "Text Datafield");
//wrap the encodedJsonObject into a root class if necessary, in this case datafield
encodedJsonObject = "{dataFields:" + encodedJsonObject + "}";
System.Net.Http.StringContent datacontent = new System.Net.Http.StringContent(encodedJsonObject, Encoding.UTF8, "application/json");

var completeResult = k2WebClient.PostAsync(actionEndpointURI, datacontent).Result;
//do something with the result, if needed
string completeResultStatus = completeResult.StatusCode.ToString();

//class used to serialize/deserialize the task item
namespace WorkflowRestAPISamples.Tasks_TaskContract
{
// Task/worklistitem data contract for the /tasks/{serialNumber} endpoint
[DataContract]
public class K2Task
{
    [DataMember(Name = "actions")]
    public Actions Actions
    { get; set; }

    [DataMember(Name = "activityDataFields")]
    public ActivityDataFields ActivityDataFields
    { get; set; }

    [DataMember(Name = "activityInstanceDestinationID")]
    public long ActivityInstanceDestinationID
    { get; set; }

    [DataMember(Name = "activityInstanceID")]
    public long ActivityInstanceID
    { get; set; }

    [DataMember(Name = "activityName")]
    public string ActivityName
    { get; set; }

    [DataMember(Name = "eventDescription")]
    public string EventDescription
    { get; set; }

    [DataMember(Name = "eventName")]
    public string EventName
    { get; set; }

    [DataMember(Name = "formURL")]
    public string FormURL
    { get; set; }

    [DataMember(Name = "instruction")]
    public string Instruction
    { get; set; }

    [DataMember(Name = "itemReferences")]
    public ActivityDataFields ItemReferences
    { get; set; }

    [DataMember(Name = "itemReferencesString")]
    public string ItemReferencesString
    { get; set; }

    [DataMember(Name = "originator")]
    public Originator Originator
    { get; set; }

    [DataMember(Name = "priority")]
    public long Priority
    { get; set; }

    [DataMember(Name = "serialNumber")]
    public string SerialNumber
    { get; set; }

    [DataMember(Name = "sleepUntil")]
    public string SleepUntil
    { get; set; }

    [DataMember(Name = "status")]
    public string Status
    { get; set; }

    [DataMember(Name = "taskStartDate")]
    public string TaskStartDate
    { get; set; }

    [DataMember(Name = "viewFlowURL")]
    public string ViewFlowURL
    { get; set; }

    [DataMember(Name = "workflowCategory")]
    public string WorkflowCategory
    { get; set; }

    [DataMember(Name = "workflowDisplayName")]
    public string WorkflowDisplayName
    { get; set; }

    [DataMember(Name = "workflowID")]
    public long WorkflowID
    { get; set; }

    [DataMember(Name = "workflowInstanceDataFields")]
    public WorkflowInstanceDataFields WorkflowInstanceDataFields
    { get; set; }

    [DataMember(Name = "dataFields")]
    public WorkflowInstanceDataFields DataFields
    { get; set; }

    [DataMember(Name = "workflowInstanceDataFieldsString")]
    public string WorkflowInstanceDataFieldsString
    { get; set; }

    [DataMember(Name = "workflowInstanceFolio")]
    public string WorkflowInstanceFolio
    { get; set; }

    [DataMember(Name = "workflowInstanceID")]
    public long WorkflowInstanceID
    { get; set; }

    [DataMember(Name = "workflowInstanceXmlFields")]
    public WorkflowInstanceXmlField[] WorkflowInstanceXmlFields
    { get; set; }

    [DataMember(Name = "workflowName")]
    public string WorkflowName
    { get; set; }
}

[DataContract]
public class WorkflowInstanceXmlField
{
    [DataMember(Name = "name")]
    public string Name
    { get; set; }

    [DataMember(Name = "value")]
    public string Value
    { get; set; }
}

[DataContract]
public class ActivityDataFields { }


[DataContract]
public class Actions
{
    [DataMember(Name = "nonBatchableActions")]
    public List<object> NonBatchableActions
    { get; set; }

    [DataMember(Name = "batchableActions")]
    public List<string> BatchableActions
    { get; set; }

    [DataMember(Name = "systemActions")]
    public List<string> SystemActions
    { get; set; }
}

[DataContract]
public class Originator
{
    [DataMember(Name = "email")]
    public string Email
    { get; set; }

    [DataMember(Name = "manager")]
    public string Manager
    { get; set; }

    [DataMember(Name = "displayName")]
    public string DisplayName
    { get; set; }

    [DataMember(Name = "fqn")]
    public string Fqn
    { get; set; }

    [DataMember(Name = "username")]
    public string Username
    { get; set; }
}

/// <summary>
/// Class that describes the datafields (variables) defined in the workflow. This class is specific to the definition of the workflow
/// You will need to set up this class based on the datafields defined for your workflow. Review the variables in the workflow to set up the necessary properties for this class
/// Set the .NET datatype for the DataMembers to the appropriate value that will parse to the underlying datafield/variable type
/// You can use the GET /api/workflow/v1/workflows/{id}/schema endpoint to discover the data fields defined for the workflow
/// </summary>
[DataContract]
public class WorkflowInstanceDataFields
{
    //TODO: Define as many fields as needed based on the workflow definition.
    //[DATAFIELDNAME] is the name of a datafield/variable defined within your workflow.
    //[DataMember(Name = "[DATAFIELDNAME]")]
    //public string [DATAFIELDNAME] { get; set; }

    [DataMember(Name = "TextVariable")]
    public string TextVariable
    { get; set; }

    [DataMember(Name = "NumberVariable")]
    public int NumberVariable
    { get; set; }

    [DataMember(Name = "BooleanVariable")]
    public Boolean BooleanVariable
    { get; set; }

    [DataMember(Name = "DecimalVariable")]
    public long DecimalVariable
    { get; set; }

    [DataMember(Name = "SampleSmartObjectRecordId")]
    public int SampleSmartObjectRecordId
    { get; set; }
}
}