Serializing Custom Activities

Every activity has serialization logic that enables the activity metadata to be represented in workflow markup.This describes workflows that can be executed by the Windows Workflow Foundation runtime 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.

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 must be created. For more information about the default serialization functionality that is used by Windows Workflow Foundation, see How to: Serialize Workflows.

When serializing activity properties in a designer, you must use the DesignerSerializationVisibilityAttribute attribute to determine whether the property will be serialized (Visible), not serialized (Hidden), or whether only the contents of the property will be serialized (Content).

By default, all custom activity properties are set to DesignerSerializationVisibility.Visible so that they are serialized by the designer. If you want to serialize a collection property, such as an ArrayList, you must decorate the property with DesignerSerializationVisibility.Content so that the contents of the ArrayList are serialized. If you do not decorate your property with this attribute, your collection property will not be serialized. For more information about designer serialization, see Designer Serialization Overview.

Serializing Generic Data Types

The DesignerSerializationVisibilityAttribute attribute is used to serialize properties of custom activities; however, not all data types can be serialized. For example, most generic data types cannot be serialized. Only generic data types that inherit from IList or IDictionary can be serialized. If you want to use those data types, you must follow these rules:

  • The DesignerSerializationVisibility.Content value must decorate the property.

  • The property is read-only.

DesignerSerializationVisibility.Content versus ContentPropertyAttribute

When serializing properties on custom activities, you have the option to use both the DesignerSerializationVisibility.Content and ContentPropertyAttribute. Although these sound similar, they are different, and you must understand the difference before you serialize your custom activities, or you will receive unexpected results.

The difference between DesignerSerializationVisibility.Content and the ContentPropertyAttribute is that whereas DesignerSerializationVisibility.Content serializes the contents of the collection data type, ContentPropertyAttribute omits a property name from being serialized to increase clarity of the serialized data. Also, the ContentPropertyAttribute decorates the class whereas the DesignerSerializationVisibility.Content decorates the property. You should never use the two to decorate a property. If you do this, a compilation error will occur.

The following example illustrates a custom activity that has a string array. It shows how the data is serialized with and without using the ContentPropertyAttribute.

[ContentProperty("Items")]
public class CustomActivity : Activity
{
    private string[] itemsList = {"item1", "item2", "item3"};

    public CustomActivity()
    {
    }

    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
    public IList<string> Items
    {
        get
        {
            return itemsList;
        }
    }

    // Activity.Execute and other overridden methods not included for clarity.
}

This is the serialized version that contains the ContentPropertyAttribute attribute.

<?xml version="1.0" encoding="utf-16"?><ns0:CustomActivity x:Name="CustomActivity" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:ns0="clr-namespace:CustomWFActivities;Assembly=CustomWFActivities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
    <x:Array Type="{x:Type p3:String}" xmlns:p3="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <ns1:String xmlns:ns1="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">item1</ns1:String>
        <ns1:String xmlns:ns1="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">item2</ns1:String>
        <ns1:String xmlns:ns1="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">item3</ns1:String>
    </x:Array>
</ns0:CustomActivity>

This is the serialized version that does not contain the ContentPropertyAttribute attribute. Note the property bold element in the example.

<?xml version="1.0" encoding="utf-16"?><ns0:CustomActivity x:Name="CustomActivity" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:ns0="clr-namespace:CustomWFActivities;Assembly=CustomWFActivities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null">
    <ns0:CustomActivity.Items Type="{x:Type p3:String}" xmlns:p3="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <ns1:String xmlns:ns1="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">item1</ns1:String>
        <ns1:String xmlns:ns1="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">item2</ns1:String>
        <ns1:String xmlns:ns1="clr-namespace:System;Assembly=mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">item3</ns1:String>
    </ns0:CustomActivity.Items>
</ns0:CustomActivity>

See Also

Concepts

How to: Serialize Workflows