Store Object in K2.net 2003 Data Field
KB000166
PRODUCT
Introduction
In some instances, it may be necessary to use and persist a strongly typed object within a K2.net 2003 Process. This is easily achieved by creating a Data Field of type Binary and then serializing the object to a byte array using a binary formatter. The serialization can then be reversed to recreate the object from the byte array when the object is required.
![]() | Important: It is strongly reccomended that only persons familiar with the following products, concepts and / or skills utilize the contents of this Knowledge Base article in their processes. The reader is assumed to be familiar with:
|
Overview
Depending on where the object needs to be stored and accessed, create an Activity or Process level Data Field and set its data type to Binary. Ensure to clear the check box for "Keep Audit Trail" unless you need to keep track of changes made to the object. Disabling the option will preevent large objects from utilising excessive amounts of storage space resources in the K2 databases. Once the Data Field is created, it may be accessed via the K2ROM.
A Data Fields' data is stored in the K2 Log database in an ntext column which allows ample space for storing objects. As a performance consideration, try to keep the objects to be stored in the Process small since storing, retrieving, serializing and de-serializing the object will have an impact on the Process' performance.
The next step is to import the required namespaces. Go to the Project properties and add imports for the following namespaces:
- System.IO
- System.Runtime.Serialization.Formatters.Binary
At each Event where the object needs to be read, add the following method to convert the byte array back into an object:
VB.NET
Dim formatter As BinaryFormatter = New BinaryFormatter()
Dim ms As MemoryStream = New MemoryStream(buffer)
Try
Return formatter.Deserialize(ms)
Catch ex As Exception
Throw ex
Finally
ms.Close()
End Try
End Function
C#
{
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream ms = new MemoryStream(buffer);
try
{
return formatter.Deserialize(ms);
}
catch (Exception ex)
{
throw ex;
}
finally
{
ms.Close();
}
}
If the code is going to be used in a number of events, it is more efficient to create a separate helper class and reference the helper class at project level. Below is an example which uses one Default Server Event to write a named value collection to a Binary Data Field called "Test" and then retrieves it in a separate Default Server Event.
VB.NET
Public Sub Main(ByVal K2 As ServerEventContext)
K2.Synchronous = True
Dim df As DataField = K2.ProcessInstance.DataFields("Test")
Dim nvc As NameValueCollection = New NameValueCollection()
nvc.Add("1", "x")
nvc.Add("2", "y")
nvc.Add("3", "z")
df.Value = ObjectToByteArray(nvc)
End Sub
Function ObjectToByteArray(ByVal obj As Object) As Byte()
Dim ms As MemoryStream = New MemoryStream()
Dim formatter As BinaryFormatter = New BinaryFormatter()
Try
formatter.Serialize(ms, obj)
Return ms.ToArray()
Catch ex As Exception
Throw ex
Finally
ms.Close()
End Try
End Function
'Get NVC from Data Field.
Public Sub Main(ByVal K2 As ServerEventContext)
K2.Synchronous = True
Dim df As DataField = K2.ProcessInstance.DataFields("Test")
Dim nvc As NameValueCollection = CType(ByteArrayToObject(CType(df.Value, Byte())), NameValueCollection)
End Sub
Public Function ByteArrayToObject(ByVal buffer() As Byte) As Object
Dim formatter As BinaryFormatter = New BinaryFormatter()
Dim ms As MemoryStream = New MemoryStream(buffer)
Try
Return formatter.Deserialize(ms)
Catch ex As Exception
Throw ex
Finally
ms.Close()
End Try
End Function
C#
public void Main(ServerEventContext K2)
{
K2.Synchronous = true;
DataField df = K2.ProcessInstance.DataFields["Test"];
NameValueCollection nvc = new NameValueCollection();
nvc.Add("1", "x");
nvc.Add("2", "y");
nvc.Add("3", "z");
df.Value = ObjectToByteArray(nvc);
}
public byte[] ObjectToByteArray(object obj)
{
MemoryStream ms = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
try
{
formatter.Serialize(ms, obj);
return ms.ToArray();
}
catch (Exception ex)
{
throw ex;
}
finally
{
ms.Close();
}
}
// Get NVC from Data Field.
public void Main(ServerEventContext K2)
{
K2.Synchronous = true;
DataField df = K2.ProcessInstance.DataFields["Test"];
NameValueCollection nvc = (NameValueCollection) ByteArrayToObject((byte[]) df.Value);
}
public object ByteArrayToObject(byte[] buffer)
{
BinaryFormatter formatter = new BinaryFormatter();
MemoryStream ms = new MemoryStream(buffer);
try
{
return formatter.Deserialize(ms);
}
catch (Exception ex)
{
throw ex;
}
finally
{
ms.Close();
}
}