SharePoint 2007 Workflows - Enhancing the ultra-basic WF

Posted on 7/9/2008 @ 12:17 AM in #SharePoint by | Feedback | 18594 views

Table of Contents for on SharePoint 2007 WF Authoring using Visual studio.

1. Setting up your environment for writing VS2005 workflows.

2. Writing an ultra basic workflow, deploying it, and slicing dicing how it worked.

3. Making that workflow more complex, adding if/else, and a bunch of activities that sort of make it more interesting.

4. Adding user interaction to that workflow using Infopath forms.

5. Authoring SharePoint 2007 Workflows using VS2008.


In my first post about writing workflows for SharePoint 2007, I talked about setting up your environment. Once your environment is setup, I used the example of writing an ultra basic workflow, basically the equivalent of Roll Of Dice, the workflow has a single code activitiy, and uses workflowProperties to update the List Item's title.

Read the ultra basic workflow before reading this blogpost.

In writing that blogpost, I demonstrated the basic concepts of authoring workflows for sharepoint using the templates provided by Microsoft. I demonstrated how and where you would write your code, drop your or inbuilt activities, and how does deploying work in both debug and production environments, how the whole thing gets packaged up as a feature, a solution etc. It was a good introduction, but I seriously don't think that will be the typical business problem you will face.

In this blogpost, I am going to enhance that same example (so read the ultra basic WF first), and add some branching logic to it.

Basically, what I am going to do is, lets say I roll dice. Great! If I get anything over 3, I should win a prize. When that prize is created, the player has a task created for him, informing him that he needs to claim a prize.

Let us begin writing it then.

In order to introduce this enhancement to our WF, the steps are pretty simple.

  1. Think, logically, how my WF will change, and what new activities will I have to drop on the surface of the WF Designer.
  2. Once you create the skeleton of the WF, fill it's bones with some flesh - write the code-behind for it.
  3. Deploy, Run, Debug, Enjoy!

Here goes -

How will my WF change?

Okay, my WF currently looks like this -

Hmm .. so "if" <dice rolled > 3> - create task & inform the winner. So my WF should now look like this -

Don't worry about the red exclamation marks. We will take care of them next.

Also note, I didn't include a "sendEmail" activity. The dude can be informed, thanks to the createTask activity.

Write the code for the WF

Excellent. Now lets get rid of those checkboxes, and write the code for the various activities we dropped.

First, the rolled dice will now have to be accessible all through the workflow. So go ahead and modify the codeActivity1_ExecuteCode method to as below -

private Int32 diceValue= 0;

 

private void codeActivity1_ExecuteCode(object sender, EventArgs e)

{

    Random rnd = new Random() ;

    diceValue = rnd.Next(1, 6);

    workflowProperties.Item["Title"] = diceValue;

    workflowProperties.Item.Update();

} 

Now that the diceValue is a private variable, go ahead and hover over the red checkmark at the IfElseBranchActivity. It should tell you that the Condition is not set. Go ahead and click on it, and set a "Declarative Rule Condition" (simpler) inside of the properties dialog for the IfElseBranchActivity. Expand that tree view for "Condition", and click the ellipses by the "Condition Expression", and specify a condition as shown below:

You would note that you have full intellisense here. very nice!

The next step is to give flesh to the bones of the createTask1 activity. This is a tad bit tricky. Just tricky, not scary.

First of all, when you hover over the red checkmark by createTaskActivity, it tells you that correlationToken isn't set. CorrelationTokens are an interesting animal. The way a workflow works is that, only a single instance of the workflow is created by the WF host. All running instances of that workflow share that instance. This has serious implications of how workflows work (think threading). But I am not going to dive into the threading aspects of WF's in this blogpost, and leave that bitchfest for another post. Over here, what you've gotta consider is, how the hell does WF keep the WF straight, if multiple WF instances, share the same WF instance? The answer is, by using CorrelationTokens.

CorrelationTokens is what will let the WF host identify, what activity wants to do what in which workflow.

There are 3 kinds of CorrelationTokens - WorkfFlow, Task, and Modification Correlation Tokens.

Workflow Tokens will apply to the following activities - OnWorkflowActivated, OnWorkflowItemChanged, OnWorkflowItemDeleted, SetState, SendEmail and UpdateAllTasks.

Task Tokens will apply to the following activities - CreateTask, CreateTaskWithContentType, UpdateTask, DeleteTask, CompleteTask, RollBackTask, OnTaskChanged, OnTaskDeleted and OnTaskCreated.

Modification Tokens will apply to the following activities - EnableWorkflowModification, OnWorkflowModified.

So in our case, we have a createTask activitiy, which means, we need to create a NEW correlation token, that applies to Tasks. This ensures that subsequent activities can find that task and act upon it. In order to do so, go to the properties of the createTask1 Activity, and set the correlation token to "taskToken". DoNot pick workflowToken as prompted by the drop down. Also set the OwnerActivityName to any parent - I choose Workflow1 (whoaa, a workflow is an activity? yep!).

The next thing to do with createTaskActivity is frankly a tad bit annoying. Double click on the createTaskActivity and it will create a createTask1_MethodInvoking for you. It will also set the createTask1.MethodInvoking property appropriately.

Now what we need to do in the MethodInvoking property, is to set the TaskID (which is a GUID), and TaskProperties. In order to do so, first you need to create two new Fields (not DependencyProperties), that you will use for TaskID and TaskProperties. You can use the following steps to acheive this.

1. Back in WF Designer, right click, properties on the createTask1 activity.

2. In the Properties, click on the ellipsis by TaskID, and go to he Bind to a New Member Tab. Fill in the form as shown below.

3. Repeat the same for TaskProperties, make sure it is bound to a new Field called "createTask1_TaskProperties1"

Perfect. Now with these two fields setup, go ahead and modify the code for createTask1_MethodInvoking to as below:

private void createTask1_MethodInvoking(object sender, EventArgs e)

{

    createTask1_TaskId1 = Guid.NewGuid();

    createTask1_TaskProperties1.AssignedTo = workflowProperties.Originator;

    createTask1_TaskProperties1.Title = "Congratulations, thou art ye winner!";

    createTask1_TaskProperties1.Description = "You have won!!! Now go and claim your prize";

    createTask1_TaskProperties1.SendEmailNotification = true;

}

 

As you can see, I am using the createTask  Activity to send the email to the user. So I don't need to worry about a sendEmail activity.

So, That's it ! 

Deploy, Run, Debug, Enjoy!

Now, I have already covered Deploy, Run, Debug, in my previous blogpost, so I won't waste too much breath on that here. So let us dive straight into "Enjoy".

  1. Create a new list.
  2. Go to List settings, and associate an instance of the Roll Of Dice workflow to that list.
  3. Add an item in there
  4. Run the workflow you created in #2 above.

Now when I "win", i.e. get a value > 3, here is what I get for my Task -

and here is how the task email looks like in Outlook 2007 -

Incredible !!!

I would recommend that you play around with a few other activities, and complicate this WF even further.

You would very shortly note that, frequently, a WF will need to talk to the end user. Ask him for feedback, intial data, maybe even let the user modify a WF. How in the world are we supposed to handle that?

Well, by creating input forms that work with the Workflow. But that's for the next blogpost.

Sound off but keep it civil:

Older comments..


On 10/17/2007 6:31:31 AM Simon Thompson said ..
Hi, Whenever i try to create a task i get an error occurred returned by the workflow. Crazy thing is that when i attach vs to the process it runs all the way through the method that i wrote. Therefore i imagine the error is occurring when the workflow actually tries to create the task.

My Code is


Private Sub createtesttask(ByVal sender As System.Object, ByVal e As System.EventArgs)


createTask2_TaskId1 = New Guid


createTask2_TaskProperties1.Title = "Hello from test 2"


createTask2_TaskProperties1.TaskType = 1


createTask2_TaskProperties1.AssignedTo = "simon@pin-point-training.co.uk"


createTask2_TaskProperties1.EmailBody = "This is the task"


createTask2_TaskProperties1.SendEmailNotification = True


end sub

The workflow works up until i get to this method, it goes through each line then after end sub it fails?

Please help, its driving me mad!!! Thanks


On 3/27/2008 3:41:05 PM Mithri said ..
Thank you so much. I am a beginner with sharepoint and was very confused with workflows. Your blog really helped me start a workflow.


On 6/9/2008 10:24:02 AM Denis said ..
You have to add ...

createTask1_TaskProperties1 = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();


On 6/26/2008 1:24:56 AM Ben said ..
Thank you for the wonderful walkthroughs!


On 12/18/2008 9:45:02 AM Ali said ..
Hi, i followed all the steps when i get the value greater than i get the message "Error Occured" but if the value of the item is <= 3 i dont get the error, the workflow completed.


what is the porblem, and i also did not get the id about task, i also didn't give any email address so how workflow send me email(to send an email procedure i cant udnerstand).


Please help me to solve this problem . Bundle of thanx in advance


On 1/15/2009 2:46:38 AM SamiUllah Khan said ..
Great Post Sahil..Wow!!! u got me started with SharePoint Workflows.


On 8/18/2009 10:48:55 PM sharmalie said ..
Great post. However, I cannot access the workflow via the internet. I configured AAM.


On 12/1/2009 8:37:48 PM felix said ..
Great post, do you know that is there any way to custom the subject of the email that auto generated by "SendEmailNotification"


On 4/27/2010 10:39:31 AM Andrew Weddle said ..
Hi there, thanks for these great posts, I am in the middle of making a new workflow for our organisation.

For those that get stuck with the "Error Occurred" make sure you read the paragraph about correlation tokens. I did not and it stuck me for 2 days!!!!


On 9/29/2010 1:13:51 PM Divya Anilkumar said ..
Thanks alot for such a nice explanation...... lookin forward for more posts...


On 3/1/2011 7:14:39 PM siddu said ..
thank you it is really helpful


On 4/11/2011 11:58:12 PM Raj said ..
Hi.


I need your help in one of my issue with custom workflow. I am developing a custom sequential workflow in VST 2010 and attaching to a document library. I am able to fire the workflow and the activities on item created and item updated. However, i am not able to get item properties values when a new document uploaded and not able to get before and after proerties when item updated.

Please help me out by providing few code samples.

for any more details, plz let me know.

thanks beforehand

raj