K2 OOB REST & WCF Services

Hello Guys,

Today I’m going to explain a very interesting yet very useful topic which is nothing but K2 Out of the box Services. Have you ever got a chance to explore about them? If your answer is No then please go through this article and get the idea what exactly they are.


Basically K2 have provided many out of the box services of all types like WCF Services, REST Services, which would serve us for many purposes as below

  • Start a workflow instance.
  • Get the worklist items.
  • Action a task.
  • Execute the smart object methods (SmartObject Services)

Let’s see how we enable these WCF and REST services.

We need to edit the web.config file located on K2 server at default location C:\Program Files (x86)\K2 blackpearl\WebServices\K2Services\web.config to enable the Workflow REST services.

In the config file we see 2 sections WCF and REST commented out. We just have to uncomment the sections which we would like to use and then restart K2 Blackpearl Service Instance

  • Now to start the workflow use below URL.

** Replace the {WorkflowName} with process full name 

  • See complete worklist Items assigned to you.

** By default all the data will be retrieved in XML format, but you can specify parameter $Format= JSON to retrieve the data in JSON format

** Note:  It will show only the worklist items which are assigned to you.

  • Get worklist item details based on SN

** Replace {SN} with SN value

  • Action a task using SN

** {SN} needs to be replaced with SN number, {Action} needs to be replaced with workflow action

SmartObject Services

Now we will know about one more interesting feature which are known as K2 SmartObject Services. Each and every SmartObject that we create in K2 can be accessed as REST or WCF Endpoints using this feature.

Now we can enable these SmartObject Services by editing the K2HostServer.exe.config file, so when exposing a SmartObject as an endpoint it will be exposed on both WCF and REST service.

Now to see the all the Smart Object’s and its methods that are exposed as endpoints we can use below URL.


And below is the sample endpoint for a SmartObject


SmartObject Name: Vijay
Method Name: GetK2Worklist()
Parameters: pUserName
$top, $format, filterXml, $skip – these are the default parameters that will be available in all endpoints.

$top – Gives you no. of records to be fetched from top of the list

$format – XML/JSON

$skip – skips no. of records from the list

Filterxml – used for filtering and sorting the list. Example below.

filterXml=<Criteria xmlns="http://schemas.k2.com/worklist/d1">
<Filter Field="ProcessFolio" Comparison="Like" ValueType="String">
Demo</Filter><Sort Field="ProcessStartDate" Order="Descending" />


All the SmartObject parameters will be given as QueryParameters and the types of methods are Create, Read, Update, Delete, List, Execute.

That’s it, this is how we can use the OutoftheBox features that are available in K2

For more Help on exploring these things refer links below

WCF Services





SmartObject Services


How to create K2 Roles and use them in Workflow? What are dynamic K2 Roles and its uses?


K2 Roles are similar to groups in Active Directory which are maintained with in K2 Server. These K2 Roles can be used in workflow for assigning tasks. These K2 Roles can be maintained by administrators for enrolling new users or removing the existing users.

K2 Roles can be added with a User or Group from the default security provider (generally Active Directory)

Now let’s see how to create a role and add users or groups or both to it.

1: Creating K2 Role

Step 1: Open K2 Workspace and navigate to Management Console tab and then right click on Roles and select Add New Role


Step 2:  It will open below screen.


Now enter Role Name & Description and Click Add Role Item which will open another pop up where you can search Users and then select them to add it to Role.

To search user you just need to type the user name in the box provided and then click enter or click search button upon which you would see the users matched with string that you provided in search box. Now select the user that you want to add in role and then click OK.

Same way you can also search for a group to add it in role.

Also you have an option to use SmartObject to fetch the users for role by using the SmartObjects tab which right beside Users Tab in above screen. You just have to select the SmartObject then the SmartObject Method and then the Field which gives you the user.

There is a checkbox with name Dynamic about which I’m going to explain it in latter part of this post.

Now click on Save Button to save the role.

2: Using K2 Role in Workflow Client Event

Now in workflow client event we have 2 ways Simple mode & Advanced Mode

Simple Mode:

In destination user’s field just drag and drop the Role you have created from Context Browser/User Browser/Roles and click finish.


Advanced Mode:

Run the client event wizard in advanced mode (Just open the Destination Users wizard click back button and select advanced checkbox to run in it in advanced mode), Now select Plan per destinationAll at once and click Next button


Now in next screen select Specify the number of the slots to be created and enter 1 and below check Resolve all roles and groups to users (by selecting this option K2 will resolve the role into individual users and the task will be created for each user)

Also below there is a checkbox saying Keep roles synchronized if you check this, K2 will automatically synchronize the role when users are added and or removed while assigning the tasks


Now just click next you will see Destination Sets Wizard where you see Default. Now click edit and add the role from context browser as shown below and click finish.


Now just deploy and run the workflow to see the tasks getting assigned to users from role.

Now let’s see what dynamic K2 Roles are

Basically in K2, Once a workflow instance is created and task is assigned to some destination users then in case if you want to add a new user as a destination user or to remove user from the destination users of the task that is already created, then it is not possible unless we redirect them manually.

Now to mitigate this situation K2 have introduced K2 Roles with dynamic option. So when we say a K2 role is dynamic then it will create only one task with the role name so that while performing the action then the K2 will dynamically check whether the user performing the action belong to the respective role or not.  So now it doesn’t matter how many users are being getting added/removed from role until the Task Action is being performed.

So we just need to check the check box with name Dynamic while creating a role to make it dynamic. By Default the interval for a role refresh is set to 10 minutes. If you want to modify the interval then in WorkSpace / Management Console/ Workflow Server/ Process you will see Roles, click it and add the role that you are using in the client event and then set the refresh interval and save.


That’s it. This is how we can make use of K2 Roles in our workflows.

Below are some of the links that would give more information on using K2 roles in workflows.




Handling multiple destination users dynamically from multiple sources.

Hello Friends,

This post is about handling multiple destination users dynamically from multiple sources.

Multiple Destinations.png

Generally we come across this situation while developing workflows, where based on some business rule or condition we need get the users from multiple sources for assigning tasks, Here I’m going to take similar type of situation as an example and will explain you how we can achieve it.


I have a student Admission Workflow in which there is an Approval Activity called Branch Approval. Now for assigning users to this Branch Approval Activity, I need check the Branch of the student and then get the users based on it. Here in this case of my requirement I have a K2 Role and an Active Directory Group and a Constant Value from where I need to get the destination users based on branch condition.

Requirement is something like below:

If Branch is

CSE then assign the task to users from K2 Role,

ECE then assign task to users from AD group users

Others then assign task to a constant user.

Now to achieve this I’m also making use of K2 inline Functions Join and Split. 

Also you refer this link How to create K2 Roles to see how we create and use K2 Role.

let’s start and see how we can do this.

Below is the workflow screenshot


Step 1: Create a new Data field with name Destination of string type, to hold the users that we fetch dynamically.

Step 2: Draw 3 lines for 3 Data Events as shown above and LineRules should be set based on data field Branch.

Step 3: Now in activity Get CSE Users, Drag a Data event and follow below steps

Step 3.1: In source field Drag JOIN function from FunctionBrowser under Text Category.


Step 3.2: Now in values field, you need to open SmartObject Explorer, navigate to System/Management/SmartObjects category and open UMUser Smartobject and select Name field from its Get Role Users method. Once you select it will ask for RoleName, pass role name and click Next and select Return all results option and click Finish. And in separator type semicolon “;” as shown below and click finish.


Step 3.3: Now in Destination field drag Destination Datafield created in step 1 and final screen should look as below Next Click Finish.



Step 4: Now similar to what we did above follow the same steps for the activity Get ECE Users, only difference would be the SmartObject that we are going to get users. As in here my requirement is to get users from AD Group if Branch is ECE, so I’m using below SmartObject to do the same.

SmartObject Name: AD Users

Category: SmartObject Server(s)/SmartObject Server/Active Directory/

Method Name: GetUserByGroup

5. ADSMO.jpg

Once you are done then the screen should like below and click finish.

6. ADFinal.jpg

Step 5: Now moving to activity Get Default Users as per our requirement if branch is OTHERS then assign to some default User so in data event source field I have hardcoded a username and assigned it to data field Destination. Screen should look as below.


I suggest you to get this constant value from some Database or some configuration setting so that it would be easy for use to change or modify this value without redeploying the workflow

Also you can assign to multiple default users by passing them as a semicolon separated string like Domain\\User1; Domain\\User2;

Step 6: Now drag a Client Event give it a name and in Destination Rule option drag SPLIT function from Function Browser under Text category.

8. Split

Now drag the Destination Data field in text field and in separator type Semicolon “;” as shown below.


Now final screen should like below


Now click Finish, configure Actions and then complete and deploy the workflow.

That’s it!! Now test the workflow to see different cases and destination users picked from different sources as per the branch.

This is how we can handle multiple destination users from multiple users dynamically.

Exploring SourceCode.Workflow.Management  GetWorkListItems method. (Worklist Criteria Filter)


This Post will explain you how to retrieve K2Worklist using SourceCode.Workflow.Management GetWorkListItems method and its Worklist Criteria Filter, using C# assembly.

We already know that K2 have provided us 2 assemblies as mentioned below, which we can use to retrieve Worklist items.

  • SourceCode.Workflow.Management
  • SourceCode.Workflow.Client.

But the difference between them is, using  SourceCode.Workflow.Management  you can get complete worklist irrespective of user whereas using SourceCode.Workflow.Client  you can’t as the latter gives the worklist of only a specific user under which the code is being run. i.e. Now if you are running the code under my credentials domain\Vijay then you will get the worklist of only this user domain\Vijay.

Now let’s see how we use this  Workflow.Management Assembly.

Step 1: Add a new Class library project using Visual Studio, give your project & class file a name and you need to add reference of below 2 assemblies to the project. You can find these assemblies in ~drive/K2Blackpearl/bin folder

using SourceCode.Hosting.Client.BaseAPI;
using SourceCode.Workflow.Management;

**Hosting.Client.BaseAPI is part of SourceCode.HostClientAPI assembly

Step 2: Create ConnectionBuilderString as below.

SCConnectionStringBuilder connectionString = 
                      new SCConnectionStringBuilder();
connectionString.Authenticate = true;
connectionString.Host = denallix;//Server Name Here
connectionString.Integrated = true;
connectionString.IsPrimaryLogin = true;
connectionString.Port = 5555;

Step 3: Create WorkflowManagementServer object and open the Connection

WorkflowManagementServer workflowServer = new WorkflowManagementServer();

Step 4: Now use workflowserver object to call get complete WorkList

WorklistItems K2WorkListItems = workflowServer.GetWorklistItems(
    string.Empty, string.Empty,string.Empty, string.Empty, string.Empty, 
    string.Empty, string.Empty);

Step 5: Don’t forget to close the connection


That’s it. Pretty Simple and fast right. Yes it is!! Now just add a console project to same above solution and call this method to debug and test this method.

Now let’s explore the options available in workflowServer.GetWorklistItems.              K2 has provided total 6 overloaded methods as below.

Option 1:

public WorklistItems GetWorklistItems(WorklistCriteria wl);

Option 2:

public WorklistItems GetWorklistItems(WorklistCriteriaFilter filter);

Option 3:

public WorklistItems GetWorklistItems(string destination, 
           string processName, string activityName, string eventName, 
           string folio, string fromDate, string toDate);

Option 4:

public WorklistItems GetWorklistItems(DateTime fromDate, 
              DateTime toDate, string destination, string processName, 
              string activityName, string eventName, string folio);

Option 5:

public WorklistItems GetWorklistItems(DateTime fromDate, 
             DateTime toDate, string destination, string processName, 
             string activityName, string eventName, string folio, 
             int start, int count, out int recordCount);


Option 6:

public WorklistItems GetWorklistItems(List<DateTime> fromDate, 
             List<DateTime> toDate, List<string> destination, 
             List<string> destinationCoparison, 
             List<string> destinationCondition, 
             List<string> processName, List<string> processNameComparison, 
             List<string> processNameCondition, List<string> activityName, 
             List<string> activityNameComparison, 
             List<string> activityNameCondition, 
             List<string> eventName, List<string> eventNameComparison, 
             List<string> eventNameCondition, List<string> folio, 
             List<string> folioComparison, List<string> folioCondition, 
             string StartIndex, string PageSize);


Out of above, option 1, 5, 6 are going to be removed soon so we shall ignore them and see how we can use the remaining options available.

Using Option 2:

public WorklistItems GetWorklistItems(WorklistCriteriaFilter filter);

To use this option we need to pass an object of type WorklistCriterialFilter which is available in assembly SourceCode.Workflow.Management.Criteria, let’s see how we can create and use this filter

In namespaces section add

using WMC = SourceCode.Workflow.Management.Criteria;

Now in the method you can use conditions as below

  • Filter for Folio = 1234
WMC.WorklistCriteriaFilter WLC = new WMC.WorklistCriteriaFilter();
WLC.AddRegularFilter(WorklistFields.Folio, WMC.Comparison.Equals, "1234");
WorklistItems K2WorkListItems = workflowServer.GetWorklistItems(WLC);
  • Filter for items where Folio contains word approval
                     WMC.Comparison.like, "%approval%");
  • Filter for items where ProcessName = POC.WKF.StudentsAdmission
                   WMC.Comparison.Equals, "POC.WKF.StudentsAdmission");
*ProcessName should be FullName of process with path.
  • Filter for items where ProcessName = WKF.StudentsAdmission AND Folio contains word approval
                     WMC.Comparison.Equals, "POC.WKF.StudentsAdmission"); 

WLC.AddRegularFilter(WorklistFields.Folio, WMC.Comparison.Like, 
                     "%approval%", WMC.RegularFilter.FilterCondition.AND);


  • Filter for items where ProcessName = WKF.StudentsAdmission OR Folio contains word approval
WLC.AddRegularFilter(WorklistFields.ProcessFullName, WMC.Comparison.Equals,

WLC.AddRegularFilter(WorklistFields.Folio, WMC.Comparison.Like, 
                     "%approval%", WMC.RegularFilter.FilterCondition.OR);


These are some of the various conditions that you can try with WorklistCriteriaFilter.

Using Option 3 & 4:

                Both of these options are self-explanatory. You just have to pass the respective parameters for applying those filters.

  • Complete Worklist
WorklistItems K2WorkListItems = 
             workflowServer.GetWorklistItems(string.Empty, string.Empty, 
             string.Empty, string.Empty, string.Empty, string.Empty, 


  • Worklist for a Process (POC.WKF.StudentsAdmission)
WorklistItems K2WorkListItems = 
              "POC.WKF.StudentsAdmission", string.Empty, string.Empty, 
              string.Empty, string.Empty, string.Empty);


Now you can try rest of the options 🙂

I’ll create another post explaining the API SourceCode.Workflow.Client.

Handling Complex Objects in K2 SmartObjects

Deserializing Complex Objects in SmartObjects


This post is in continuation to my previous post K2 Integration with REST Api Services where I’ve created an SMO for a REST Api. As api’s return you serialized response, we need to further deserialize them using the Deserialize methods of that particular type/object.

Now if you see the result in below screen shot which is the result of WeatherAPI, it is providing a Serialized objects for Clouds, Coord, Main, Sys. Now to get the individual properties of the above mentioned serialized types/objects, we need to further deserialize them. Lets see how we can do.


Now the SMO which we have created in last post needs to be modified using K2 Designer. Select the method from service instance (Here it is GetWeatherbyCityName) and map the properties as shown in below screen shots.



Now if you see the mapped properties in above screen shot, Clouds is mapped to a memo property Clouds (Clouds) which is the serialized result from api. Once the method is created click add and select Deserialize method of clouds from service instance as shown below.


Now the Deserialize method takes the serialized value as input and returns the individual properties of Clouds type. You need to map the serialized value which we got from above method as input and map the individual return properties to SMO properties (Here the property is ALL).


Now similar to above add deserialize methods of other class types (Coord, Main..) and map their respective properties.


Now once you finish,  it should like below.


That’s it. Click Finish and execute the SMO to see the individual properties as below



CloudsALL is the deserialized value from Clouds Object, Similarly CoordinatesLatitude, CoordinatesLongitude are the desreialized values from Coord object, similarly Main Object Values you can see there.

That’s it. This is how we can Deserialize complex objects.

Here we have seen only single level of complexity which means for every weather result object, we get only one cloud object, one Coord object and so on. But there could be cases of result with multi-level complexity which means for every single weather result object there could be multiple cloud objects or multiple Coord objects and so on. In that case we may not be able to deserialize as we did above. We need to create separate methods for each object like GetCloudsbyCityName, GetCoordbyCityName, GetMainValuesbyCityName and handle the methods in same way as we did above.

Also in some cases, Api methods takes serialized objects as an input values, in that case we need to use the serialize method of that objects first which returns us the serialized value and then we need to pass this serialized value to the main method (just opposite to the way we did above).

This is how we can handle complex objects in K2 Smartobjects.


K2 Integration with REST Api Services


We know that K2 has ability to integrate with multiple LOB’s, let us have a look at how we can integrate K2 with REST Api’s.

This post will explain you

  • How we create a REST Service Instance for a REST Api using K2 REST Service broker.
  • Create a Smart Object to get the data from REST Api.
  • Execute that Smart Object Method.

Creating REST Service Instance

K2 uses Swagger Definition of REST Service for creating a Service Instance. Swagger definition can be obtained by using an online Tool RESTUnited.com

RESTUnited.com is an online tool to generate the swagger definition of a service.

Now for this sample I have used the openWeatherMap.org which provides free REST API’s of weather information with multiple querying options for free along with some paid featured services too.

To Use their free services you need to register with your mail ID and some other basic details. Once registered, you would get an API Key which you need to use for all the API calls.

They have provided enough documentation of their wide range of API’s with details at below link



Here is a sample call to one of the REST Api which takes city name as input and gives the weather response. Please note that API key needs to be passed as URL Parameter APPID



Once you have Api ready, we need to get the swagger definition of that service. Now to get that use RESTUnited.com an online tool. You need to register here for a free trail to use the tool. Now follow the instructions as given at below link.


Once you have completed all the steps you will see below screen in which you would be able to download the Swagger definition by selecting Swagger Tab and clicking Export Button.


Once you have the Swagger Definition/Descriptor file,

  • Open SmartObjects – Services – Tester utility tool(find this utility at C:/Program Files/K2 Blackpearl/bin),
  • Expand ServiceObject Explorer right click on REST,
  • Click Register ServiceInstance and you will be seeing below screen where in highlighted area you need to give the path of that swagger file that we just downloaded.


  • Now Click Next button and you should see below screen and Click Add.



Now you should be able to see the Service Instance Added under the REST Category as below, you can explore the methods and types under it from here.


Creating Smart Object

Now it’s time to create a smart object using this Service Instance. We can use K2 Designer or Visual Studio or K2 Studio for creating but here I would prefer to use the same SmartObjects – Services – Tester utility tool to create as it’s the fastest way to create and publish an SMO.

Just give a right click on the object type or method that you want to use from Service Instance and Select Create SmartObject, now you would be seeing below screen. In that give you’re SmartObject a Name and select the folder under Category dropdown and Click Publish SmartObject


That’s it. Now navigate to your SMO and execute the method to see the results.

Below are the serialized data responses from the Api, now to get the individual Values, we need to deserialize them. For knowing how to deserialize the serialized responses check here Handling Complex Objects in K2 SmartObjects


This is how we can integrate K2 with REST Api Services .

Cheers Guys!!!

Mixed mode assembly error fix while using K2 Assemblies

Helooo Every one

Among the articles that I have posted at the beginning of my blog UnCode K2, one of the article explains about File Load Exception which occurs when you are referencing a .Net Assembly built on Version 2, with in a project which is being built on Version 4 or above.


More or less all source code assemblies which we get from K2 were built on .Net Framework Version 2 and when we use them in our version 4 projects we would encounter this issue.

As a work around we have to add some additional configuration settings in your app.config file to get around this issue.

    <startup useLegacyV2RuntimeActivationPolicy="true"> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />


So basically while you run your application, above mentioned configuration inform .Net runtime to use mixed mode CLR 2 assemblies in a .NET 4 application so that they would load without any issue.

I thought above mentioned configuration will work in all cases, but actually it’s not.

Recently I was working on creating some Custom WCF Services which has dependencies on custom assemblies in which they have referredK2 source code assemblies. Now I’m able to build the project without any issue, but at the runtime I have encountered the above mentioned issue when I’m calling those methods. I tried using above mentioned configuration in WCF Service App Config file but it didn’t work.

After some research on this, I found that WCF Services are creating its config at runtime and it’s not picking up the configuration changes that I have set. So as a workaround for this issue we need to set these settings dynamically via Code.

Below is the class file which imports the current runtime as an interface object and set the legacy v2 runtime and returns true or false based on success.

    public static class ActivateLegacyRuntime
        public static bool SetLegacyV2Runtime()
            ICLRRuntimeInfo objICLRRuntimeInfo =
                return true;
            catch (COMException)
                return false;

        private interface ICLRRuntimeInfo
            void xGetVersionString();
            void xGetRuntimeDirectory();
            void xIsLoaded();
            void xIsLoadable();
            void xLoadErrorString();
            void xLoadLibrary();
            void xGetProcAddress();
            void xGetInterface();
            void xSetDefaultStartupFlags();
            void xGetDefaultStartupFlags();

            [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
            void BindAsLegacyV2Runtime();


Now once we have our class file ready, we just have to call the method SetLegacyV2Runtime and based on what it returns we need to call the Custom assembly method.

   //Call the assembly Method
  //Show message cannot load the assembly

This have worked for me. Hope it works for you too.

Thanks to authors for these articles at below links which helped me in resolving this thing.