Downloads
140458.zip

The complete workflow story was significantly improved in SharePoint 2010 over the previous version’s story as Microsoft invested in SharePoint Designer 2010 (SPD2010) capabilities in creating custom workflows with the SharePoint 2010 release. SPD2010 is a tool that can create powerful declarative workflows, but previous versions were dismissed by many because its workflows were tied to a specific list at design time. That meant there was not a good option for creating and deploying workflows with a simple copy-paste deployment between a development and production environment. 

SPD2010 changed this with the ability to support reusable (aka content type) workflows that could be created in one environment, saved as a sandbox solution package, and easily saved and deployed to another environment. It also received other very important improvements such as impersonation steps, a better workflow designer, the ability to import Visio 2010 authored workflows, and a significantly improved task approval process designer.

 

Challenges with SharePoint Designer 2010 based Workflows

However with all these improvements, a few things still lead people to dismiss SPD2010 as their workflow tool. For instance SPD2010 can’t support loops or state machine workflows. SPD2010’s declarative workflows are limited to sequential workflows that can have decision points (“IF” statements), but there is no looping process.

In addition, SPD2010 doesn’t provide low level debugging or elevation of privileges when you have a need to do so in the business process. Debugging is limited to monitoring what inputs are provided to the workflow and how it reacts. Another big limitation of SPD2010 authored workflows is that they can only access content within the same site where they’re running; they can’t access content from other sites, site collections or external feeds, and Web services.

 

Challenges with Visual Studio 2010-Based Workflows

Many customers concluded their only option was to move to Visual Studio 2010 (VS2010) for creating their workflow solutions. This presented other challenges, though. For instance, all VS2010 workflows are code based and must be deployed as fully trusted farm solutions; it’s not possible to deploy a workflow built in VS2010 to the sandbox. VS2010 workflows are usually built only by developers, not by power users or the business analysts who best understand the business process being automated by the workflow.

 

Addressing SharePoint Designer 2010 Limitations

What I saw in the first few months after SharePoint 2010 was released was that many people were still in what I considered the SharePoint 2007 mode of thinking with respect to workflow. This thought process usually involved ditching SPD2010 as the workflow tool and moving over to building the workflow with VS2010 when one of the aforementioned limitations was encountered. I find this to be quite disappointing because building workflows with VS2010 leaves a lot on the table. You lose the ability to have declarative-only workflows that can be deployed to the sandbox, your developers aren’t in charge of building a business process, and worst of all, there’s more custom code that needs to be maintained.

The reason this is so disappointing is because what I typically see is that the majority of the workflow process can be expressed using SPD2010, with only one or two small pieces that SP2010 can’t handle. These few pieces push people to VS2010. The analogy “throwing out the baby with the bathwater” comes to mind. Instead of throwing the whole workflow out, why not address the problem?

One option available to customers is to have a developer empower those building workflows with SPD2010 by using VS2010. This is facilitated by creating a custom action (otherwise known as an activity) with VS2010 and deploying it to SharePoint 2010. The next time someone opens the site in SPD2010, the custom action will be available in the last of actions that can be used in the declarative workflow. These custom actions can be deployed either to the sandbox or as a fully trusted farm solution and are scoped to a particular site collection.

 

Capabilities of Custom Actions

A custom action is really no different than the type of actions (aka activities) in VS2010-based workflows. You’re simply wrapping up some custom code in a reusable component. This custom component could call out to another Web service or feed; it could impersonate a more privileged user or even access content residing in other SharePoint sites or site collections.

There must be a catch, right? Not really. You can address almost every single SPD2010 limitation with a custom action created in VS2010. The two biggest exceptions to this rule are the inability to simulate state machine workflows and the ability to create sophisticated loops.

SharePoint 2010 allows developers to create two different types of custom actions for use within declarative workflows authored with SPD2010: sandboxed actions & full trust actions. Let’s now look at these options.

 

Sample Sandbox Custom Action

In my opinion, developers should try to create sandbox custom actions before creating full trust custom actions, because the declarative SPD2010-based workflows they will be used within can be run from the sandbox. A mixed story of having to tell a customer “you need to deploy this farm trust solution for a custom action that is used by this sandbox solution” doesn’t sound so good, nor does it permit the entire solution to be used within most hosted SharePoint deployments.

As with other sandboxed solutions, a sandboxed custom action will have such limitations as the inability to issue Web service calls, database calls, or impersonate a user with elevated permissions. The following code sample in Listing 1 shows what a custom sandboxed custom action looks like. This one doesn’t do much other than set the value of the current site’s description.

This solution was built with VS2010 using the Empty SharePoint Project template. After the action is built, you need to register it using an element manifest file in the Feature that will make SPD2010 aware of the action. This file, which you can see in Listing 2, contains some basic information about the action as well as the designer to use within the rich SPD2010 interface:

Build and package the project to create a WSP and add it to a site collection’s solution gallery. After the solution is activated in the solution gallery, the next time someone opens the site in SPD2010, he or she will see the new custom action, which Figure 1 and Figure 2 show.

 

Sample Farm Trust Custom Action

At times, the sandboxed custom action won’t give you everything you need. For instance, maybe you want to make a call to a custom database or an external Web service, two things which sandboxed solutions can’t do. These require creating a full blown custom activity in VS2010. To show the amount of code required in a custom action deployed as a farm trusted solution, look at the following code sample, seen in Listing 3, which does the same thing as the previous sandboxed custom action.

Just like the sandboxed custom action, this project will require a separate custom actions file to make SPD2010 aware of the custom action and can be used the exact same way deployed to the {SharePointRoot}\TEMPLATE\{LCID}\Workflow directory. For more details around creating both sandboxed and full trust custom actions refer to chapter 11 in Inside SharePoint 2010 (MSPress), by Ted Pattison, Andrew Connell, Scot Hillier, and David Mann, or refer to the SharePoint SDK on MSDN.

 

Limiting Custom Code, Empowering People

I hope you will consider the concept of having developers create custom actions using VS2010 to augment and further empower SPD2010 workflows. This approach limits the amount of custom code deployed, and thus maintained, in an environment, and it also ensures many more people can create custom workflows with SPD2010 instead of limiting that process to developers who have VS2010.


 

Listing 1: Code for a custom sandboxed custom action

 

namespace CPT.Samples.SandboxedAction {

 public class UpdateWebDescriptionAction {

 

  public Hashtable UpdateWebPropertyBagValue(SPUserCodeWorkflowContext context) {

   using (SPSite siteCollection = new SPSite(context.CurrentWebUrl)) {

    using (SPWeb site = siteCollection.OpenWeb(context.CurrentWebUrl)) {

     site.Description = "Updated from custom sandbox action at " + DateTime.Now.ToString();

    }

   }

 

   return new Hashtable();

  }

 

 }

}

 

 

Listing 2: Code to register an action using an element manifest file

 

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

 <WorkflowActions>

  <Action Name="Update Site Description (sandboxed)"

      SandboxedFunction="true"

      Assembly="$SharePoint.Project.AssemblyFullName$"

      ClassName="CPT.Samples.SandboxedAction.UpdateWebDescriptionAction"

      FunctionName="UpdateWebPropertyBagValue"

      UsesCurrentItem="false"

      AppliesTo="all"

      Category="CPT Actions">

   <RuleDesigner Sentence="Update current site description to current timestemp." />

   <Parameters>

    <Parameter Name="__Context" Direction="In" DesignerType="Hide"

          Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext, Microsoft.SharePoint.WorkflowActions" />

   </Parameters>

  </Action>

 </WorkflowActions>

</Elements>

Listing 3: Code required in a custom action deployed as a farm trusted solution

 

public partial class UpdateWebDescriptionActivity : Activity {

  public static DependencyProperty __ContextProperty =

   DependencyProperty.Register("__Context", typeof(WorkflowContext), typeof(UpdateWebDescriptionActivity));

 

  public WorkflowContext __Context {

   get { return (WorkflowContext)base.GetValue(__ContextProperty); }

   set { base.SetValue(__ContextProperty, value); }

  }

 

  protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) {

   __Context.Web.Description = "Updated from custom sandbox action at " + DateTime.Now.ToString();

   return ActivityExecutionStatus.Closed;

  }

 }