DotNet Development, SharePoint Customizing, Silverlight, MS Infrastructure and other tips and tricks

Introduction in Custom WF Activities

Posted by PANVEGA on January 20, 2009

Microsoft Office SharePoint Designer 2007 allows non-developers to create custom workflows in a straightforward way by using the workflow designer it provides. During the process, the user “glues” together different activities that represent the steps for the workflow. There are numerous activities one can use and the list is extensible. Developers can use Microsoft Visual Studio 2005 to build additional activities and deploy them, so that they are available in Office SharePoint Designer 2007.

My example in the post extendes the default out of the box Activity in the SP Designer (Copy List item). In the default activity you can only copy an item in the same site. I added a new attribute DestinationListUrl which copies the select item from the root list by using the SP Object Model to the destination list in an other site collection.


On Codeplex you find some useful custom SP Activities


All the actions you see in the SPD workflow designer are activities that live in a DLL on the SharePoint box (e.g. Microsoft.SharePoint.WorkflowActions.dll). There’s a .ACTIONS XML file in the SharePoint TEMPLATE directory on the local file system that describes how to display each of that DLL’s activities in a sentence form and bind parameters to the activity’s properties. SPD reads all .ACTIONS files in the directory, then shows all the activities in the designer and pushes the data you enter down into the activity’s properties.

Preparing the Development Environment

To make a custom activity available for the workflow designer in Office SharePoint Designer 2007, follow these steps:

  1. Use Visual Studio 2005 to create a Workflow Activity library project containing a class that inherits from the System.Workflow.Activities.SequenceActivity class.
  2. Install Visual Studio 2005 Extensions for the .NET Framework 3.0 (Windows Workflow Foundation).
  3. Provide access to the path C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\1033\Workflow on the server running Windows SharePoint Services 3.0
  4. Expose properties as DependencyProperty types if you want the workflow engine to interact with it at run time.
  5. Override the Execute method to code the logic of the activity that returns a status value back to the workflow runtime engine.
  6. Sign the project and compile it in a .NET assembly to deploy in the global assembly cache.
  7. Create an .ACTIONS file containing the metadata for the custom activity that is loaded by the workflow designer in Office SharePoint Designer 2007.
  8. Authorize the custom activity in the web.config file for the targeted IIS Web application.

We begin by creating a Workflow Activity Library project. You can work with the activity in the designer or in the code editor. An activity can contain one single action or it can group multiple activities together, resulting in a composite activity.

Create a new Windows Workflow Activity Library project

To begin, let’s cover the components necessary to create a custom Windows Workflow Activity and make it available in SPD.

The main pieces of the puzzle are as follows:

  1. The assembly that contains the custom Workflow Activity class.
  2. The web.config file corresponding to the SharePoint Web Application on your server where the custom Workflow Activity will be used.
  3. The WSS.ACTIONS file on your SharePoint server that registers Workflow Actions with SPD.

To create the assembly that contains the custom Workflow Activity class, perform the following steps.

  1. Open VS 2005.
  2. Click File| New | Project.
  3. In the Project Types tree select Workflow.
  4. In the Templates list box select Workflow Activity Library.
  5. In the Name text box enter Sample.ActivityLibrary.
  6. Click the OK button.

First of all open your Visual Studio and navigate to File-> New-> Project -> Workflow Activity Library

In the next step go to the Solution Explorer, right click on References to bring up the context menu. Select Add Reference from the Add Reference dialog box, add references to the Windows SharePoint.Services and the Windows SharePoint Services WorkflowActions.

using Microsoft.SharePoint;
using Microsoft.SharePoint.Workflow;
using Microsoft.SharePoint.WorkflowActions;

The activity wouldn’t be useful if it didn’t pass information on, so to make it available to the rest of the workflow, we will need to use property promotion. Property promotion consists of getters and setters to allow the property to be bound to variables outside of the activity. For this example, we need to derive the Workflow Context object to retrieve the current SharePoint Site, the List Id for which the activity is attached and
the current List Item to provide Item Level Security.

Create Dependency Properties

Properties in the activity are exposed in the workflow designer in Office SharePoint Designer 2007, or the Workflow Designer in Visual Studio 2005, and are populated only when the workflow instance is started at run time. You create and expose these properties by declaring them as type DependencyProperty.

At first we have to specify the Dependency Properties, these are the Properties which interacts with SPD Workflow Wizard. The Declaration is as following:

The next step is to define the properties for internal use. There are several Options which can be given to the property (see belowe).

public static DependencyProperty __ContextProperty = System.Workflow.ComponentModel.DependencyProperty.Register(“__Context“, typeof(WorkflowContext), typeof(CrossSite));

public WorkflowContext __Context
return ((WorkflowContext)(base.GetValue(__ContextProperty)));
base.SetValue(__ContextProperty, value);

public static DependencyProperty ListIdProperty = System.Workflow.ComponentModel.DependencyProperty.Register(“ListId”, typeof(string), typeof(CrossSite));

public string ListId
return ((string)(base.GetValue(ListIdProperty)));
base.SetValue(ListIdProperty, value);

etc. ……


  • typeof(CrossSite) is my activity class name
  • declare the appropriate return value (WorkflowContext, string, bool, int …..)

Notice that the __Context Property is of type WorkflowContext. This property is the most important for the implementation of this activity.

As for the implementation of the activity, we have to override the Execute method. In the following code I am using the WorkflowContext to get a reference to the list of custom templates in my site and creating the new site based on the input template. As for the name of the site, I am taking the value of the input field name for the current item. Notice the usage of all the input properties.

The Execute Method

The Windows Workflow run-time engine calls the Execute method of the activity. This method is inherited from the base SequenceActivity class; this is where you write the business logic for the activity. The following code example uses the Microsoft.SharePoint.dll and the object model exposed by it to create a task item in the indicated list in the site that the workflow designer specifies while defining the template.

short example:

protected override ActivityExecutionStatus
Execute(ActivityExecutionContext executionContext)  {
try  {
SPSite sitecollection = new SPSite(this.SiteUrl);
SPWeb web = sitecollection.OpenWeb();
SPUser user = web.Users[this.AssignTo[0].ToString()];
SPList list = web.Lists[this.ListName];
SPListItem item = list.Items.Add();
item[“Title”] = this.TaskTitle;
item[“AssignedTo”] = user;
catch (Exception ex)   {
EventLog.WriteEntry(“MSDN Workflow”, ex.ToString());
return ActivityExecutionStatus.Closed;

Note: The Execute method returns an ActivityExecutionStatus value. In the previous example, this indicates that the work is finished.

The last step which we have to do with coding is to rename the SequenceActivity to Activity.

public partial class YourCustomActivity: Activity

Now we have to sign the assembly with a strong name and build the solution. I will describe the Deployment procedure for a custom Activity in another post.

Deploy the dll to the GAC and add it to the web.config file

The next step is to compile your activity and deploy it to the GAC  (C:\WINDOWS\assembly). The assembly must be signed. You can drag and drop this into the GAC directory or use the .net gacutil tool. Keep a note of the assembly, class, version, and public key token, as they’ll be used later on in the .ACTIONS file.

But before SharePoint will run the activity, it has to know that our new dll’s types are safe and trusted so we need to add it to the web.config file. Updating the config file’s authorized types means this activity can be used in declarative workflows in WSS (the workflow equivalent of ‘safe for scripting’).

  1. Navigate to the root port directory of the SharePoint Site for which the activity is created located in “C:\inetpub\wwwroot\wss\virtualdirectories” and search for “web.config” file. These xml files contain lists of authorized types that can be used for that server port.
  2. Open the file and add your authorizedTypetag at the end of the node.

<authorizedType Assembly=”CopyListItemExtended, Version=, Culture=neutral, PublicKeyToken=XXXXXXXXXX” Namespace=”CopyListItemExtended”  TypeName=”*” Authorized=”True” />

The activity dll is now ready to be run on the server

Create a ACTIONS file for the Activity parameters

The final step of preparing an activity for SPD is to change the WSS.ACTIONS file. This xml file describes the types of the promoted properties of the activity and how to map them into a rules sentence.

  1. Navigate to “C:\Program Files\Common Files\Microsoft Shared\web server
    extensions\12\TEMPLATE\1033\Workflow” folder and open the WSS.ACTIONS file.
  2. Create a new file in the Folder with the Datatype .ACTIONS e.g. CopyItem.ACTIONS. After an IIS reset SharePoint add all ACTION files together. e.g.                                                                                                                                 <?xml version=”1.0″ encoding=”utf-8″?>
    <Actions><Action ……></Action></Actions>
  3. or you can navigate to the end of the file.
  4. Append the following code before the </Actions> tag.

<Action Name=”Copy List Item Extended” ClassName=”CopyListItemExtended”
Assembly=”CopyListItemExtended, Version=, Culture=neutral, PublicKeyToken=xxxxxxxxxxxxxx”
AppliesTo=”all” Category=”Custom Actions”>
<RuleDesigner Sentence=”%1 item in %2 to list at %3, %4 existing items. Store resulting list item id in %5″>
<FieldBind Field=”Move” DesignerType=”Dropdown” Text=”choose” Id=”1″>
<Option Name=”Move” Value=”true”/>
<Option Name=”Copy” Value=”false”/>
<FieldBind Field=”ListId,ListItem” Text=”this list” Id=”2″ DesignerType=”ChooseListItem” />
<FieldBind Field=”DestinationListUrl” Text=”this url” Id=”3″ DesignerType=”TextArea” />
<FieldBind Field=”Overwrite” DesignerType=”Dropdown” Text=”choose” Id=”4″>
<Option Name=”Overwrite” Value=”true”/>
<Option Name=”Do not Overwrite” Value=”false”/>
<FieldBind Field=”OutListItemID” DesignerType=”ParameterNames” Text=”variable” Id=”5″/>
<Parameter Name=”__Context” Type=”Microsoft.SharePoint.WorkflowActions.WorkflowContext” Direction=”In” />
<Parameter Name=”ListId” Type=”System.String, mscorlib” Direction=”In” />


The “Action” tag defines basic information about the action with the following attributes:

· Name – name of the action (this is what SPD displays in its actions list)

· ClassName – the name of the activity, i.e. Namespace.WorkflowClassName

· Assembly – details of the GAC’ed assembly

· AppliesTo – describes what types of lists this activity can be used for, either “list”,
“doclib”, or “all”

· Category – category that SPD will display in the categories for available actions

The next section is the “RuleDesigner” section. This describes a rule sentence for the action as well as how to bind them to the activity properties. These are the sentences SPD displays in its rules wizard. The variable parameters in the sentence, e.g. %1, etc., are exposed as customization links. When displayed, they will be replaced with the “FieldBind” tags below, where %1 will be replaced with the FieldBind with Id=1,etc.The “FieldBind” tag describes each variable parameter. The “Field” attribute corresponds to the parameter, or activity property, as it is described in the Parameter tag in the markup.

“DesignerType” describes what type of interface to show when the user clicks on the link. For example, if you want to show a select user dialog, you would use “SinglePerson” for the designer type. The “Text” attribute is how the field is displayed in the sentence.

Finally, the “Parameters” tag tells the RuleDesigner how to map the fields to the promoted properties on the workflow activity.Each “Parameter” describes the name of the property (which should match the corresponding FieldBind above), the system type of the property, and direction (“In” means that the activity gets that parameter, and “Out” means the activity sets that parameter).

The recommended way is to create a Solution wirh a feature: You find more information about Solution Deployment in my previous posts:

One last tip at the end:

The most common pitfall is adding a .ACTIONS or web.config entry which doesn’t exactly match your custom DLL. If you find that the action shows up in SPD, but nothing appears when it is selected, verify that the entries you’ve made match the activity class exactly. If a particular binding won’t change, make sure your .ACTIONS field bindings match the promoted properties in your DLL.

More Information:


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: