Friday 10 September 2010

How To... Create and debug a state machine workflow in SharePoint 2010 using Visual Studio 2010 and c# Part 3

Part 3 coding and assigning activities to our workflow states

This is Part 3 of 4 for creating a state machine workflow using SharePoint 2010 with Visual Studio 2010 and c#. To read the introductions please click here.
To read part 2 click here


In this part we will;


  • Start to code logic for our different workflow states

  • Set up the Transformation of the workflow from one state to another

  • Add and code new activities to support or states within the workflow

Configure the Initial state

  • Single click the event driven activity that is within the Init State Activity

  • Change the Name in the properties window to eventInitStateActivity 1

  • Double click eventInitStateActivity 1 in the initial state

You will now be presented with the onWorkflowActivated activity.




Now add a Set state activity just beneath the onworkflowactivated1 activity.

  • From the toolbar drag a set state activity (from Windows Workflow 3.0 Activities) beneath the onworkflowactivated1 activity.
    Note the error suggesting the TargetStateName is not set.

  • Set its TargetStateName property to InDevelopment_State
    Note the error has now gone. This activity simply moves the workflow from one state to another.
    Notice there is a breadcrumb at the top left of our design canvas.

  • Click ‘WorkFlowDevJobs’ from the breadcrumb on the design surface. This will take you back up one level within our workflow.

    You will now see a connecting line between the InDevelopment_State and the Init_State .

This depicts the process flow within the state machine.


We have now configured the initial state to transform directly to the InDevelopment_State as soon as a new instance of the workflow is started.

  • Save your work and rebuild the project to check for errors.

Configure the InDevelopment State

Now we are going to create a task for our development user when we enter the indevelopment state.

  • Select the InDevelopment_State

  • Right click then select Add state initialization.

This event will fire when the workflow initially enters this state.

  • Drag a createtask (from the SharePoint toolbox group) activity to the stateIn itializationActivity1

  • Note the error about correlation tokens

Before we address the correlation token error we are going to rename the CreateTask1 activity to InDevlopmentCreateTask1.

  • Change the Name property from createTask1 to InDevelopmentCreateTask1


We now need to create a correlation token for each of our states, so starting with the InDevelopment_State:

  • Select the InDevelopmentCreateTask1 activity

  • Select the Correlation Token property and type InDevelopmentToken. This will create the correlation token for this state.

  • Set the ownerActivityName (you may need to expand Correlation Token first) and set this to the value of InDevelopment_State.
Now we need to set our task properties, we will do this by creating a new taskid and a new task properties field. These will be used in code later.
  • Select task id in the properties

  • Select the elipses which will display the binding dialog

  • Select the Bind to a new member tab

  • Click create a new field then click ok – this will create a new member name called InDevelopmentCreateTask1_TaskId1.

Now do the same with task properties property.
  • Select task properties from the properties window

  • Select the elipses which will display the binding dialog

  • Select the Bind to a new member tab

  • Click create a new field then click ok – this will create a new member name called InDevelopmentCreateTask1_TaskProperties1
In the methodinvoking property lets create an event handler method
  • Type InDevCreateTask1_MethodInvoking into the MethodInvoking property, and then press enter.
  • This should load you to the code window for the new handler. Add the following code to the handler:


  • Click the design surface tab WorkFlowDevJobs.cs [design]; this will take you to the design view.

  • Click the WorkFlowDevJobs in the breadcrumb.

  • Save your work and rebuild the solution to check for errors.

Summary


We have configured the Init_State to transform initially to the InDevelopment_State when a new workflow instance is started. In other words this means our first stage in our process is the In Development stage. We have also configured the InDevelopment_State so it creates a task for our development user when the state is entered.

Listening to see if our task has changed for the ‘In development’ state
We now intend to configure an event handler / listener that will listen for when our task has changed. When the listener intercepts the fact that the task has changed we will check to see if the task is 100% complete before moving to the next stage – namely the InTesting_State.

  • Right click our InDeveloment stage

  • Select Add EventDriven from the menu

  • Drag an OnTaskChanged Activity onto the label ‘Drop Activities here’

  • Change the name of OnTaskChanged1 to InDevOnTaskChanged1
    Note the error informing us about correlation tokens.

Now we will change some of the properties associated with out new activity

  • Set the task id to the existing field that we created earlier by clicking the elpses on the tasked property. The field will be listed on the Bind to Existing member tab.





  • Set the AfterProperties property by binding to a new field using the same binding dialog as the previous step (Select the ellipses in the AfterProperties property).

    The field name will be defaulted to InDevOnTaskChanged1_AfterProperties1.

  • Set the BeforeProperties property by binding to a new field using the same binding dialog as the previous step (Select the ellipses in the BeforeProperties property).

    The field name will be defaulted to InDevOnTaskChanged1_BeforeProperties1.

  • Set the correlation token property to the InDevelopment token from the dropdown.

  • Generate an event handler using the invoked property, Enter InDevOnTaskChanged1_Invoked. Pressing enter will launch you into code view.

  • Enter the following code:



  • Click the WorkflowDevJobs.cs [design] tab in visual studio
  • Save your work and rebuild the solution to check for errors.

    Checking if the task has actually changed.
    We will now use an if else activity to check if the task has actually been completed.

  • Drag an if else activity onto the design surface below the InDevOnTaskChanged1 activity – as depicted below:




    Add a code method to test if our task is 100 % complete.
  • Click the WorkflowDevJobs.cs tab. This will go into code view.

  • Add a new method in the class:



  • Select the WorkflowDevJobs.cs design tab

  • Select IfElseBranchActivity1

  • the condition property to Code Condition

  • expand the + next to condition property and select the sub property which is also called condition – select our method IsDevComplete.

Now we shall set the state for when our new code condition is met.

  • Drag a setstate activity under the ifelseactivity1 branch. This will be used to set the workflow state to InTesting if the inDevelopment task is called complete.

  • Click the SetStaeActivity2 that you have just placed onto the design surface.

  • Select the Targetstate property and set to InTesting_State.
Your If Else logic should look like this:





  • Click on the WorkFlowDevJobs link in the breadcrumb ,
    You should now see a connection between the InDevelopment_State and select the InTesting_State.



Summary So Far


We have now wired up a code condition that checks if the task that is in the InDevelopment_State is 100% complete, if not nothing happens, however if it is 100% Complete then the state is set to the InTesting_State.

Configure The In Testing Stage.


  • Right Click the In_Testing_state in the diagram.

  • Select Add StateInitialization from the menu.

  • Drag a create task activity to the stateInitializationActivity2
    Set its properties

  • Name: CreateInTestingTask

  • CorrelationToken: InTestingToken

  • OwnerActivity: InTesting_State

  • Create a new field binding for the TaskID and TaskProperties

  • Set TaskID = CreateInTestingTask_TaskId1

  • Set TaskProperties : CreteInTestingTask_TaskProperties1

Create a code method for the property methodinvoking:


  • MethodInvoking = CreateTestingTask_MethodInvoking

  • Add the following code:





  • Click on the WorkFlowDevJobs.cs design tab

  • Click the WorkFlowDevJobs link in the breadcrumb


    Listening to see if our task has changed for the ‘In Testing’ state

  • Right click InTesting_State and select add event driven from the menu.

  • Drag an onTaskChanged activity to eventDrivenActivity3

  • Set the correlation token and name for the onTaskChanged activity

  • Set the name for this activity to : InTestingTaskChanged

  • Set the correlation token to InTestingToken

  • Set the Owner Activity to InTesting_State

We will also need to set the taskID and before/after properties for this activity.

  • Set the taskID to bind to the existing member CreateInTestingTask_TaskId1

  • Set the beforeproperties to bind to a new field : InTestingTaskChangedChanged_BeforeProperties1

  • Set the afterproperties to bind to a new field : InTestingTaskChangedChanged _AfterProperties1

  • Set the invoked property to generate an event handler set to : InTestingTaskChanged_Invoked

    Add the following code:



  • Click the WorkflowDevJobs.cs.design tab.

  • Drag an ‘if else’ activity beneath the InTestingTaskchanged activity.
    We will use this if else activity to decide if we are should transition our workflow state.


Create a code method to check the after properties of the task is 100 % complete.

  • Click the WorkFlowDevJobs.cs tab, this will give you the code view window.

  • Add the following code to test to see if the task is 100% complete.





    Just like we did when we configured the InDeveloment_State we will set the ‘if else’ code condition to point to our code method IsTestComplete.
  • Click the WorkFlowDevJobs.cs[design] tab to view the design surface
  • Click the IfElseBranchActivity3 and lets set its properties
  • Set Condition to Code Condition
  • Expand the + sign of condition to expose sub properties
  • Set the Sub Condition property to IsTestComplete
  • Save your work and rebuild the solution to check for any errors.

Sanity Check on Business Rules

We could at this point simply add a set state activity to transform our workflow state to completed, however we would like to put a further check into the workflow to see if the task has been rejected back to development or if we assume the task is completed. To do this we will nest another ‘if else’ activity after our IfElseActivity3.

In summary we will code this additional check to cope with the following business rules:

  • If the tester has marked the task as 100% complete but has used the word ‘rejected’ in the description we will transform the workflow back to the InDevelopment_State.
  • If the tester has marked the task as 100% complete and we do not have the word ‘rejected’ in the description then we will set the workflow to the final completed state.

    Nest another if /else activity.
  • Select IfElseBranchActivity3
  • Drag a new ‘if else’ activity and place it below IFElseBranchActivity3

Your workflow should now look something likethis:




To avoid any confusion we should rename some of these branch activities to something meaningful.

  • Select the IfElseBranchActivity5 and call this BranchRejected
  • Select the IfElseBranchActivity6 and call this BranchCompleted
  • Drag a set state activity beneath the BranchRejected Activity, give this a name of SetDevelopment
  • Set the TargetStateName as InDevelopment_State
  • Drag a set state activity beneath the BranchCompleted Activity, give this a name of SetComplete.
  • Set the TargetStateName as Completed_State.

Your workflow should now look something like this:





  • Save your work and build the solution to check for errors

    You should notice an error appear: Activity ‘BranchRejected’ validation failed: Property ‘Condition’ is not set. This was intentional and we shall now address this.

  • Click on WorkFlowDevJobs.cs, this will display the code view of our workflow.
  • Add the following code:



  • Click the WorkFlowDevJobs.cs[Design] tab to view the design surface
  • Select the ‘ BranchRejected’ activity
  • Change the condition Property to Code Condition
  • Click the + sign next to the condition property to expose sub properties.
  • Select the sub condition property and select IsRejected

  • Now just as a quick sanity check:
  • Save your work and rebuild the solution checking for errors
  • Click the workFlowDevJobs link in the breadcrumb and review the state diagram ensuring the connections appear as you would expect.




Summary

This will complete our configuring and coding of our workflow. We will move to the next part which will focus on test driving our new workflow. The workflow is simple in terms of its states or stages, basically a new document will automatically be assigned to our development user, when the developer has completed the job they will assign a task completion of 100%. This will trigger the document to enter the In Testing stage, when the tester has reviewed the document he or she will then complete the task as 100%, if he or she decided that the job needs to go back to development for some rework the word rejected will be placed somewhere in the task description. If the task description contains the word rejected anywhere then the state of the document will go back to development otherwise the document will go to the completed state.



Click here to read part 4

No comments:

Post a Comment