Custom SharePoint Designer Activity

SharePoint 2010 comes with several powerful pre-defined workflows and activities. But what if the out of the box workflow activities don’t (fully) meet your requirements? You could of course go fully Windows Workflow Foundation and develop the complete workflow in Visual Studio 2010. Another option is to develop a custom Activity and make it available to SharePoint Designer. This way the end user can tune and modify the workflow without the need to bother the developer.

Things we need:
• Visual Studio 2010
• SharePoint 2010 (any edition will work)
• SharePoint Designer 2010

Create the activity

1. Create a new C# Workflow Activity Library Project
2. Add references and “using” statements to the following assemblies:

using System.Workflow.ComponentModel;
using System.Workflow.Activities;
using System.ComponentModel;
using Microsoft.SharePoint;

Make sure your project targets Framework 3.5 and everything should be available right from the “Add Reference” dialog.

3. Modify Activity1.cs which will contain our activity

Of course we now need some properties for our workflow activity. In order to access the properties from our custom activity, we need some form of special declaration. This way we can ensure SharePoint Designer hooks up all the needed information. This declaration is done with the help of what is called “Dependency Properties”. They start off with a standard .Net property with get and set methods and then get registered as a “DependencyProperty”. You do this by appending “Property” to the name (this is important) and declaring it like this:

public static DependencyProperty SiteUrlProperty = DependencyProperty.Register("SiteUrl",typeof(string), typeof(CreateSite), new PropertyMetadata(""));

I want my activity to create a site, so I need the following properties at least:
• SiteUrl: url of the root site where the new site will be created
• SiteName: name of the new site
• SiteTemplate: template to be used for the new site

After we setup the properties, we need to override the Execute method:

protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
            return ActivityExecutionStatus.Closed;

4. Sign the assembly with a strong named key.

Create the deployment

Because we are targeting SharePoint Designer, it is now the time to work on our deployment.
1. Add a new Empty SharePoint Project to our solution and make it a Farm Solution.
2. Add the following mapped SharePoint folder: {SharePointRoot}\Template\1033\Workflow
3. Create the Actions xml file

  <Actions Sequential="then" Parallel="and">
    <Action Name="Create Site" ClassName="CustomActivityLibrary.CustomActivityCreateSite" Assembly="CustomActivityLibrary, Version=, Culture=neutral, PublicKeyToken=1b2a70b987e8b655" AppliesTo="all" Category="Custom SPD Activity">
      <RuleDesigner Sentence="Site Name %1 in root site %2 using template %3.">
        <FieldBind Field="SiteName" Text="Site Name" DesignerType="TextArea" Id="1"/>
        <FieldBind Field="SiteUrl" Text="Url of root site" Id="2" DesignerType="TextArea"/>
        <FieldBind Field="SiteTemplate" Text="Name of the template" Id="3" DesignerType="TextArea"/>
        <Parameter Name="SiteName" Type="System.String, mscorlib" Direction="In" />
        <Parameter Name="SiteUrl" Type="System.String, mscorlib" Direction="In" />
        <Parameter Name="SiteTemplate" Type="System.String, mscorlib" Direction="In" />

4. Add the project output from the ActivityLibrary as an additional assembly to the Package.

5. Add the assembly as an authorized type to the web.config:

<authorizedType Assembly="CustomActivityLibrary, Version=, Culture=neutral, PublicKeyToken=1b2a70b987e8b655" Namespace="CustomActivityLibrary" TypeName="*" Authorized="True" />

And voila, we can now make use of our own custom activity:

Deployment on a production machine, is of course somewhat different. You need the following components:
1. Your workflow activity library (the assembly)
2. The workflow .actions file (place it in the Template\1033\workflow folder)
3. The SafeControl entry in the web.config
4. The authorizedType entry in the web.config

Sample code: CustomActivitesLibrarySource (ZIP)