Tag Archives: .NET

Using K2 WorklistCriteria

In my previous post, I’ve discussed on how to use K2 blackpearl’s SourceCode.Worklist.Client API for basic functions like start Process Instance, open Worklist, open Worklist Item and action a Worklist Item. All these functions are straight forward (that’s about all you can do with it) except the open Worklist  function.

Normally, when you use the OpenWorklist method, you will like to have some form of filtering. It could be a filter to show the user his/her tasks based on the current department website listed or some custom prioritization logic to help the user to focus on the tasks at hand. To make this filtering possible, you will need to make use of the WorklistCriteria class.

Using K2 WorklistCriteria

To use the WorklistCriteria class, you will need to carry out the same open/close workflow connection steps in my previous post, which I’m not going to repeat here. Once that’s done, you will need to create an instance of the class.

You will need to add your filters here, which we will discuss in the next section and lastly pass the object into the OpenWorklist method.

So in the full picture, your codes will look like this:

So if you execute the codes now, it will return all Worklist Items of the current user.

My result without filter

Filter Basics

Now, to add a filter, you will need to call on the AddFilterField which has 3 variations:

WCField is the list of properties you can filter on and they are pretty much self explanatory.

Do take note that WorklistItemStatus comparision uses the following values:

WCCompare lists the comparison operators you can use in the filter:

If you notice, there is no “greater than”, “greater than or equal”, “less than” and “less than or equal” operators here, so you will need to put some thoughts into your mathematical operations (=

WCLogical is the joining operator between 2 filters. This will be discussed in more details in a subsequent section.

SubField is a string value used to reference additional key names like Data Field name during comparison.

Object is a object value for your comparison.

So if you just want to filter and show all Worklist Item with “Available” status, the code will look like this:

When using my test Worklist, I’ll get:

Result showing all “Available” status only

Using AND and OR Logical Operators

Using the AND and OR filter is pretty straight forward.

In my AND join example, I’m going to create a filter that requires the Process Name to start with “C” and the Worklist Item status to be “Open”.

Result for Process start with “C” and status = “Open”

In my OR join example, I’m going to create a filter that requires the Worklist Item status to be “Available” or “Open”.

Status = “Available” OR “Open”

Using the Other Operators

Other than AND and OR operators, the following shows what the other operators does:

StartBracket: Draws the “(” operator for the given filter.

AndBracket: Adds the AND operator and closes the filter with a “)” operator.

OrBracket: Adds the OR operator and closes the filter with a “)” operator.

EndBracket: Closes the filter with a “)” operator, if you have a StartBracket earlier on

Filtering by Process or Activity Data/Xml Field

If you need to filter by Process or Activity Data or Xml Field, you will need to pass in the field name in the SubField like the following:


Well, the above details should get you through majority of your needs to create a custom Worklist. Enjoy!!

Providing a friendly error message for your K2 error

5 May 2017: I’ve updated this post for 4.6.10 and above here.

Be it on smartforms or your custom ASP.NET forms, the OpenWorklistItem call will return the following error if the current User did not pass the validation rule on K2 Server:

OpenWorklistItem error

For the K2 Designer and Admins, it’s a simple fact that the User is not the Destination User of this Activity. To the Users of this System, they will be like “What the heck are you trying to say?!?”. So how can we help the Users to better understand what is going on without calling us every time a cryptic message appears?

Find these cryptic out-of-box messages

These messages are stored as a template in [K2 blackpearl folder]\Host Server\bin\HostServerLogging.config.

The error message for ID 24411

In this file, you will find all the message templates used by K2. The first three numbers of the MsgID represents a logical section. So for example, MsgID starting with 244 are relating to security.

Of course, you can just modify this file directly, restart your K2 blackpearl Server services and all messages will be friendlier. But what happens on upgrade? Well, there’s a high chance that it will be replaced by the default copy in the installer, so it will be a hassle to make comparisons and update the entire list every time you upgrade. My take? Don’t touch this file unless you are willing to do all the additional work.

Friendly message via ASP.NET

Once you know the message you are looking out for, the rest will be using your try-catch block to capture the error thrown and look out for the MsgID in your error message body.

Friendly message via K2 smartforms

In smartforms, you will need to make use of the Error Handling condition – Error Occurred and read the message via the System Values > Error node.

  1. Open your Rule Configuration Wizard.

    Rule Wizard Configuration
  2. Add the Error Occurred condition. This will be executed when an error occurs in this Rule.

    Error Occurred condition
  3. Add the An advanced condition is true condition. This condition should be with Error Occurred to create a AND condition like the following:

    An advanced condition is true with Error occurred
  4. Click on an advance condition link, followed by the Add button to add a new row.

    Add a new row of condition
  5. From the Context Browser, expand System Values > Error. Drag the Error Message node and drop it to the Left column text box. Select Contains for the Operator and fill in the MsgID code you are looking for in the Right column text box. Click OK to save and close the dialog.

    Fill in the conditions
  6. Add your friendly message and any other rules(e.g. disable form, navigate to another form etc).

    Add a message
  7. Lastly, let’s test and see the result. 172-result


Have fun!


Using K2 Workflow Client API

[Updated: 4/6/2015]: Added reference to usage of WorklistCriteria here.

The SourceCode.Workflow.Client assembly provides the access to interact with the K2 blackpearl Server in the context of a User. This means that the API will not be able to query, for example, for all Users who has a Worklist Item from a specific Process. You will need to use SourceCode.Workflow.Management assembly for this. This API, however will allow the current User to impersonate as any other User within K2, if the account has the Impersonate rights on the Workflow Server. We will see more about this. Now down to the basics.

K2 Workflow Client API

Adding a reference to the assembly
  1. SourceCode.Workflow.Client
  2. SourceCode.Hosting.Client

These 2 assemblies can be found in the following location:

  • GAC – This is if you are working from within the K2 sever
  • K2 blackpearl’s bin folder – If you have the client components installed on your machine. The default path is C:\Program Files (x86)\K2 blackpearl\bin.
  • K2 Host Server’s bin folder – If you are working from within the K2 server. The default path is C:\Program Files (x86)\K2 blackpearl\Host Server\bin.

Note: The API call is carried out via RPC, so it means that as long as you have the required DLLs with your application, you will be able to make the call even if you did not install the K2 Client Components on that machine.


Open a connection to K2 blackpearl server

To open a connection, you only need the following:

For the Open method, there are a couple of variations:

  • Open(string Server): This requires a server name that can be resolved by the DNS/Host File or an IP.
  • Open(string Server, string ConStr): The 2nd parameter provides a connection string information. See ConnectionSetup.ConnectionString property.
  • Open(ConnectionSetup setup): This requires a ConnectionSetup object. You can provide a different log in credentials here.


User Property

Once the connection is opened, the User property will show the current logged on account:

Connection object’s User property

If you find that the User property does not match the current logged on User in your ASP.NET page, it means that your web.config file is not configured to impersonate the current logged on User. Make sure the following is present in your web.config file:


Impersonate another User

If the current logged on User has the Impersonate rights on the Workflow Server:

You can execute the following code to impersonate as any User within the K2 environment:


Closing a connection to K2 blackpearl server

When you are done with the connection, always remember to close it by calling on the Close or Dispose method. You should always wrap the connection in a Using block:

Or a try-catch and/or finally block:


Start a Process Instance

To start a new process instance (a.k.a new workflow instance),  you will need to create a ProcessInstance object first.

The path to process is a combination of the root project folder name, followed by any folders’ name till the process. So in the following example:

K2 Designer for Visual Studio

K2 Workspace

The path will be “TestProject1\ModuleA\Process1”.

With the ProcessInstance object created, you will be able to update the Folio and process level Data Fields before the process instance starts. This procedure is optional.

When the necessary updates on the ProcessInstance object is completed, you will need the Connection object’s StartProcessInstance method call to kick start the process instance.

Note: The StartProcessInstance method runs asynchronously by default. If you need the method to be executed synchronously, pass a 2nd parameter “true”:


Opening a Worklist

A work list (task list) is a collection of work list items (task list items) that is assigned to the current logged on user. You need to call on the OpenWorklist method of the Connection object and it will return a Worklist object, which is a collection of WorklistItems. The following is a sample method call:

Note: The OpenWorklist method without any input parameter will return the entire collection of WorklistItems of the current User. This is not going to be efficient and very time consuming if the current User has thousands of tasks. To overcome this, we should use a Filter with the OpenWorklist method, which we will discuss in a separate article you can find here. [Updated: 4/6/2015]


Open WorklistItem

Now, the WorklistItem is a single task assigned to the current User. It has the information of the current process instance and also the Activity Destination Instance. This means that we can draw the following information from it (Just to name a few):

  • WorklistItem.ProcessInstance.Folio: The Folio of the current process instance.
  • WorklistItem.ProcessInstance.DataField[“myField”].Value: Get the process level data field.
  • WorklistItem.Data: The full URL of the task form.
  • WorklistItem.Actions: The configured Actions for this task.

To open a work list item, it means getting K2 to assign a slot to this user. This method will also validate if the current user is the valid Destination User and whether the work list item is still available for actioning.

SN stands for Serial Number, which is an identifier that the K2 server will insert as a query string parameter with the task form URL.

Just for information, the serial number comprises of:

  • Process Instance Id; and
  • Activity Destination Instance Id

The 2 values will be separated by an underscore ‘_’ symbol. For example: SN=123_45


Execution the work list item action

And of course, with the WorklistItem, you will be able to execute the configured Action (i.e. when User clicks on the Approve button).

Note: The action name needs to be spelled exactly the same as configured in the process.

Note: The Execute method runs asynchronously by default. If you need the method to be executed synchronously, pass a 2nd parameter “true”.


Here are some “more complete” sample codes if you are still unclear:

Start a new process instance

Open work list

Open work list Item

Execute an action


Have fun!!