SharePoint: Using classes for workflow association data
I am using workflow with association form in one of my current SharePoint projects. When workflow is added to list there are some parameters that user must insert. Workflow instances are able to persist association data and to be more flexible the association data is saved as XML string. But in the code it is more convenient to use object instead of XML strings. I will show you how I solved the situation.
This is the class I want to use to keep association data.
C#
public class WorkflowConfig
{
public List<string> UserFields = new List<string>();
public string DateField = string.Empty;
public int NotifyBefore;
}
VB.NET
Public Class WorkflowConfig
Public UserFields As New List(Of String)()
Public DateField As String = String.Empty
Public NotifyBefore As Integer
End Class
Now I need something to convert objects based on this class to XML. I need also something to restore objects from XML. Luckily .Net Framework has XmlSerializer class in System.Xml.Serialization namespace. Lazy as I am I really don’t want to write factory classes and other fancy infrastructure that will be overkill when thinking about our requirements.
We need to write two methods – one that serializes the object and the other that takes XML and returns object of type WorkflowConfig. I add these two methods to my workflow configuration class as static methods.
C#
public class WorkflowConfig
{
[XmlArray("Fields")]
[XmlArrayItem("Field")]
public List<string> UserFields = new List<string>();
public string DateField = string.Empty;
public int NotifyBefore;
public static string Serialize(WorkflowConfig conf)
{
var confString = string.Empty;
using (var stream = new MemoryStream())
{
var serializer = new XmlSerializer(typeof(WorkflowConfig));
serializer.Serialize(stream, conf);
stream.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(stream))
{
confString = reader.ReadToEnd();
}
}
return confString;
}
public static WorkflowConfig Deserialize(string xml)
{
var serializer = new XmlSerializer(typeof(WorkflowConfig));
WorkflowConfig conf = null;
using (var stream = new MemoryStream(xml.Length))
{
var bytes = Encoding.UTF8.GetBytes(xml);
stream.Write(bytes, 0, bytes.Length);
stream.Seek(0, SeekOrigin.Begin);
conf = (WorkflowConfig)serializer.Deserialize(stream);
}
return conf;
}
}
VB.NET
Public Class WorkflowConfig
<XmlArray("Fields")> _
<XmlArrayItem("Field")> _
Public UserFields As New List(Of String)()
Public DateField As String = String.Empty
Public NotifyBefore As Integer
Public Shared Function Serialize(ByVal conf As WorkflowConfig) As String
Dim confString = String.Empty
Using stream = New MemoryStream()
Dim serializer = New XmlSerializer(GetType(WorkflowConfig))
serializer.Serialize(stream, conf)
stream.Seek(0, SeekOrigin.Begin)
Using reader = New StreamReader(stream)
confString = reader.ReadToEnd()
End Using
End Using
Return confString
End Function
Public Shared Function Deserialize(ByVal xml As String) As WorkflowConfig
Dim serializer = New XmlSerializer(GetType(WorkflowConfig))
Dim conf As WorkflowConfig = Nothing
Using stream = New MemoryStream(xml.Length)
Dim bytes = Encoding.UTF8.GetBytes(xml)
stream.Write(bytes, 0, bytes.Length)
stream.Seek(0, SeekOrigin.Begin)
conf = DirectCast(serializer.Deserialize(stream), WorkflowConfig)
End Using
Return conf
End Function
End Class
Now let’s try out this code using simple test program.
C#
class Program
{
static void Main(string[] args)
{
var cfg = new WorkflowConfig();
cfg.UserFields.Add("Author");
cfg.UserFields.Add("Invited");
cfg.DateField = "MeetingDate";
cfg.NotifyBefore = 2;
Debug.WriteLine(WorkflowConfig.Serialize(cfg));
}
}
VB.NET
Class Program
Private Shared Sub Main(ByVal args As String())
Dim cfg = New WorkflowConfig()
cfg.UserFields.Add("Author")
cfg.UserFields.Add("Invited")
cfg.DateField = "MeetingDate"
cfg.NotifyBefore = 2
Debug.WriteLine(WorkflowConfig.Serialize(cfg))
End Sub
End Class
Our little test program produces XML output shown below. We can save this XML to workflow association data. Later we can use WorkflowConfig.Deserialize() method to get our object back from XML.
<?xml version="1.0"?>
<WorkflowConfig
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Fields>
<Field>Author</Field>
<Field>Invited</Field>
</Fields>
<DateField>MeetingDate</DateField>
<NotifyBefore>2</NotifyBefore>
</WorkflowConfig>
That’s it. Simple and clear. If you plan to use this code then make the modifications you need and don’t forget adding your error handling code to static methods.