Tag Archive for 'workflow'

Exposing the State of a SharePoint Workflow Instance

Scenario

I have a fairly straight-forward sequential approval workflow that has an EnableModificationActivity that is in scope for just about the entirety of the workflow. My modification form is an ASPX page that gives the user the ability to enable/disable approval steps that have not occurred yet in the workflow. Since the workflow is able to be modified multiple times, I would like the form to reflect the current state of the workflow, meaning it should show which activities are currently enabled or disabled.

Solution

So here is the approach I ended up taking…

  1. I created a Plain Old CLR Object (POCO) class specific for holding state information my particular workflow that is capable of being XML Serialized. I’ll call this the “State Object” going forward.
  2. I created a reusable class called “WorkflowStateManager” that is capable of loading and saving single State Objects for a given SPWorkflow. This class is accessible by both the workflow and the modification form.
    • Save State Implementation:
      1. XML serializes the object to a string
      2. Sets the serialized string on the SPWorkflow list item’s property bag and calls the property bag’s Update() method
    • Load State Implementation (Essentially the reverse of the Save State implementation)
      1. Gets the serialized string from the SPWorkflow list item’s property bag
      2. XML Deserialize the string into the State Object
  3. When the workflow is activated, I construct a new State Object, initialize various properties on it, and save it using the WorkflowStateManager.
  4. As the workflow progresses, I load and update the State Object as needed in the following manner:
    • Use the WorkflowStateManager to load the current State Object
    • Make workflow decisions based on the State Object’s values
    • Make desired changes to the State Object
    • Use the WorkflowStateManager to save the State Object
  5. Now, my modification form is also able to load, manipulate, and save the State Object using the WorkflowStateManager, and in turn expose the current state of the workflow to the user.

I hope this might be of benefit to someone.

SharePoint Workflow: Getting Replicator ChildData within a CreateTask Activity

Disclaimer: the following code requires version 3.5 of the .Net Framework, but can easily be modified to run using .Net 2.0

Scenario

So I was asked to develop a fairly straight forward approval activity in which several users were to be assigned an approval task in parallel.  Microsoft offers its ReplicatorActivity to accomplish just this.  The gotcha is that when running the ReplicatorActivity in parallel, the CurrentIndex property of the replicator is always the last index value of its child data.  So how do you know which ChildData item the replicator is currently executing upon?

Solution

What I came up with seems a little hacky, but has been working beautifully for me.  Here it goes…

The replicator contains a DynamicActivities property which holds references to each of the replicated activities it creates.  Using Linq, we can easily convert this collection to a list, and then determine the index of the current activity within our newly converted activity list.  The following example shows how I am using this method to access the current child data from within a CreateTask activity:

        private void createTask_Invoked(object sender, EventArgs e)
        {
            var createTask = (CreateTask)sender;
            string approver = (string)WorkflowUtils
                .GetReplicatorChildData(createTask);
 
            ...
 
        }

And the magic happens within our WorkflowUtils helper class:

    public static class WorkflowUtils
    {
        public static Activity GetTopMostReplicatorChild(Activity activity)
        {
            var parent = activity.Parent;
            if (parent == null)
                return null;
 
            if (parent is ReplicatorActivity)
                return activity;
 
            return GetTopMostReplicatorChild(activity.Parent);
        }
 
        public static object GetReplicatorChildData(Activity activity)
        {
            var topMostChild = GetTopMostReplicatorChild(activity);
            var replicator = (ReplicatorActivity)topMostChild.Parent;
 
            int currentIndex = replicator.DynamicActivities
                .ToList()
                .IndexOf(topMostChild);
 
            return replicator.CurrentChildData[currentIndex];
        }
    }

Top 5 Most Useful SharePoint Links of the Month

So I just completed and released to production my first approval workflow application using ASP.Net forms and Visual Studio Workflow Designer. I have combed through hundreds of web pages working out many many kinks. These are the top 5 links for this month (measured on subjective scale of usefulness to me for completing my project):

Get Public Key Token Visual Studio Trick

SharePoint Workflow Basics

Design and Bind ASPX Forms to Workflow

Locked Workflow tasks Bug

WSS WebService DISCO and WSDL Generator