How to: Serialize Workflows
The Windows Workflow Foundation framework provides a serialization infrastructure that is used to serialize and deserialize a workflow. By default, a workflow is serialized to workflow markup according to certain formatting rules.
Default Serialization
Developers of new activities automatically get default serialization to workflow markup. This default serialization should be sufficient for most activities, but sometimes a custom serializer might be required.
The following is an example of how to use the WorkflowMarkupSerializer class to serialize a workflow. In this example the workflow has a single custom activity of type ConsoleWriteLineActivity
activity.
// Construct a workflow and then serialize
// it to XAML. Start with the root workflow activity.
SequentialWorkflowActivity wf =
new SequentialWorkflowActivity();
// Create a ConsoleWriteLineActivity, set
// its Msg property, and add it to the workflow.
ConsoleWriteLineActivity crw = new ConsoleWriteLineActivity();
crw.Msg = "Hello World!";
wf.Activities.Add(crw);
// Serialize the workflow to XAML
// and write it to the Console.
StringBuilder sb = new StringBuilder();
XmlWriter writer = XmlTextWriter.Create(sb);
WorkflowMarkupSerializer serializer =
new WorkflowMarkupSerializer();
serializer.Serialize(writer, wf);
writer.Close();
Console.WriteLine(sb);
The markup for this workflow looks like the following example. Note the namespace prefix for the ConsoleWriteLineActivity
activity element.
<?xml version="1.0" encoding="utf-16"?>
<SequentialWorkflowActivity x:Name="SequentialWorkflowActivity"
xmlns:ns0="clr-namespace:XamlCodeExamples;Assembly=XamlCodeExamples,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/workflow">
<ns0:ConsoleWriteLineActivity
x:Name="consoleWriteLineActivity1"
Msg="Hello World!" />
</SequentialWorkflowActivity>
Serialization Infrastructure
The Windows Workflow Foundation default serialization infrastructure provides all the types required to serialize the default activities. For more information about the Windows Workflow Foundation framework default activity set, see Windows Workflow Foundation Activities.
The following are the important classes in the serialization infrastructure:
The WorkflowMarkupSerializer class is the base serialization type used in the serialization infrastructure. This type provides some of the basic services for serialization that implement the serialization rules. The serializers for activities or any other custom serializers for custom activities must inherit from this class.
The ActivityMarkupSerializer class inherits from the WorkflowMarkupSerializer class. This type is used to serialize all basic activities. These are activities that are not composite activities.
The CompositeActivityMarkupSerializer class inherits from the ActivityMarkupSerializer class and provides the serialization for composite activities. CompositeActivityMarkupSerializer adds more methods to process child activities, which can be serialized using their own serialization providers.
Serialization Format Rules
Workflow markup is the serialized form of object hierarchies. How an object is serialized depends on the object's properties. There are two main rules that help in the serialization of type instances:
The object's type definition is the element name in XAML.
The object's properties map to the attributes on the element definition in XAML.
The following code example shows an object serialization for the ConsoleWriteLineActivity
activity.
public partial class ConsoleWriteLineActivity :
System.Workflow.ComponentModel.Activity
{
public ConsoleWriteLineActivity()
{
InitializeComponent();
}
public string Msg { get; set; }
protected override ActivityExecutionStatus
Execute(ActivityExecutionContext executionContext)
{
Console.WriteLine(Msg);
return ActivityExecutionStatus.Closed;
}
}
An instance of this class is serialized as shown in the following XAML code example. In this example, the namespace declaration that contains the assembly information for the custom activity is included with the activity.
<ns0:ConsoleWriteLineActivity
x:Name="consoleWriteLineActivity1"
Msg="Hello World!"
xmlns:x="http://schemas.microsoft.comwinfx/2006/xaml"
xmlns:ns0="clr-namespace:XamlCodeExamples;Assembly=XamlCodeExamples,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
The code example shows that the string property Msg
became an attribute of the ConsoleWriteLineActivity
element. The value "Hello World!" is the actual value for the property.
A class definition can be much more complex than the code example's ConsoleWriteLineActivity
class. Other rules apply in the serialization of more complex objects. For more sample code on workflow serialization, see Workflow Serialization Sample.
Note
WorkflowMarkupSerializer does not support serialization of nested types. For example, if you create a custom activity and define a nested type within that activity, you receive an error during compile time.
Custom Serialization
You can customize the serialization format. The customization can be done at two levels. A new serialization infrastructure can be provided, which includes a custom serialization format and a serialization for each type. The other serialization can be done at the level of activities. The serialization infrastructure is still workflow markup as provided by the Windows Workflow Foundation authoring framework, but the individual activity layout can be changed.
Customizing Activities
If you create a custom serializer, activity authors must provide a reference to the custom serializer as shown in the following code example.
[DesignerSerializer(typeof(ExampleActivityMarkupSerializer), typeof(WorkflowMarkupSerializer))]
public class ExampleActivity : Activity
{
}
<DesignerSerializer(GetType(ExampleActivityMarkupSerializer), GetType(WorkflowMarkupSerializer))> _
Public Class ExampleActivity
Inherits Activity
End Class
The serializer is specified by using the DesignerSerializer
attribute, which has two parameters:
The first parameter specifies the serializer that should be used to serialize the instance of the class on which the attribute has been defined.
The second parameter specifies the base type of the serializer. The base type of the serializer specifies the serialization scheme to use.
In the DesignerSerializer code example, the second attribute specifies WorkflowMarkupSerializer. This means that the base serialization infrastructure to be used is based on WorkflowMarkupSerializer.
Defining the Custom Serializer
The custom serializer is a class that must be inherited from a base serialization type. In the DesignerSerializer code example, ExampleActivityMarkupSerializer
is a custom serializer for the ExampleActivity
class. ExampleActivityMarkupSerializer
inherits from WorkflowMarkupSerializer, which is the second parameter of the attribute.
When the serialization manager starts to serialize an activity, it uses the class definition to determine the custom serializer type by finding the base type of the WorkflowMarkupSerializer in the second parameter of the DesignerSerializer
attribute. It then gets an instance of the serializer and uses it. For additional sample code, see Custom Serialization Sample.
Workflow Markup
Workflow markup describes workflows that can be executed by the Windows Workflow Foundation run-time engine. Workflow markup is a component serialization scheme that is used to describe the activity hierarchies that make up workflows and the associated logic that is activated when the activities raise events.
Workflow markup does not have any fixed grammar to describe it. It defines a general scheme that can be used to represent a hierarchy of objects, together with their properties and methods. Every activity has serialization logic that enables the activity metadata to be represented in markup that is defined for the object.
For more information, see Using Workflow Markup.
See Also
Reference
System.Workflow.ComponentModel.Serialization
Concepts
Serializing Custom Activities
How to: Compile Workflows
Using Workflow Markup