Building State Machine Document Approval Workflows for SharePoint Server 2007 Using Visual Studio 2008

Summary:  Learn how to use Visual Studio 2008 templates to create a state machine document approval workflow for Microsoft Office SharePoint Server 2007.

Office Visual How To

Applies to:  2007 Microsoft Office System, Microsoft Office SharePoint Server 2007, Microsoft Visual Studio 2008

Mike Rand, 3Sharp

June 2008

Overview

State machine workflows enable you to model real-world events and business processes in ways that are not available to sequential workflows. By modeling a workflow on states and transitions, a state machine workflow gives you the ability to create powerful business tools. Microsoft Visual Studio 2008 includes templates that provide a great starting point for creating state machine workflows. This Microsoft Office Visual How To describe how to use Visual Studio 2008 to create a state machine document approval workflow for Microsoft Office SharePoint Server 2007.

Code It

The scenario in this Office Visual How To is a simple expense report approval process. An expense report has been submitted and must be approved or rejected. You can manage this process by using states. Table 1 shows a breakdown of the states and transitions.

Table 1. State/Transitions

StateEventState
ReportInitialStateeventInitWorkflowReportSubmittedState
ReportSubmittedStateeventReviewReportReportApprovedState
ReportSubmittedStateeventReviewReportReportRejectedState
ReportApprovedStatestateInitApprovedStateReportCompleteState
ReportRejectedStatestateInitReportRejectedStateReportCompleteState

This example uses the Microsoft Office InfoPath 2007 Expense Report form in a modified version. For more information about how to modify this form, see Creating a Custom Approval Workflow for SharePoint Server 2007 Using SharePoint Designer 2007. You will also use a custom task form that is created by following the steps in Building an Expense Report Approval Workflow for SharePoint Server 2007 Using Visual Studio 2008.

Creating a Visual Studio 2008 State Machine Workflow Project

First, you create a Visual Studio project to build your workflow.

To create a Visual Studio 2008 State Machine Workflow project

  1. Open Visual Studio 2008.

  2. On the File menu, point to New, and then click Project.

  3. Under the Office Project type, select the SharePoint 2007 State Machine Workflow project template.

  4. In the Name text box, type ExpenseReportStateMachineWF, and then click OK.

  5. Type a valid SharePoint Server Web URL. This scenario uses http://moss.litwareinc.com/expense. Click Next.

  6. Select a library or list to associate with the workflow, or accept the default. Click Next.Rename the

  7. StateMachineWorkflowActivity from the default workflow1.cs to ExpenseReportStateMachineWorkflow.

Laying Out a State Machine Workflow

Now you can set up your workflow. You start by laying out the workflow in the designer and updating all required properties. Later, you add the code to drive your workflow.

To lay out a state machine workflow

  1. By default, the workflow contains a state named Workflow1InitalState. Open the Properties window and rename this state to ReportInitialState. For now, do not worry about the EventDriven activity eventDrivenActivity1; you will return to that later.

  2. Open the Toolbox. Expand the SharePoint Workflow controls and the Windows Workflow v3.0 controls.

  3. In the Windows Workflow v3.0 category, select State, and drag it onto the designer surface.

  4. Open the Properties window, and rename this state to ReportSubmittedState.

  5. Add three more states to the document surface, and rename them ReportApprovedState, ReportRejectedState, and ReportCompleteState.Next, set your initial state. Right-click ReportInitialState, and then select

  6. Set as Initial State.

    This adds a small green circle icon to the state in the upper-left corner, as shown in Figure 1.

    Figure 1. Initial state icon

    Initial state icon

  7. Next, set your completed state. Right-click ReportCompleteState, and select Set as Completed State.

    This adds a small red circle icon to the state in the upper-left corner, as shown in Figure 2.

    Figure 2. Completed state icon

    Completed state icon

    Now that you have all of your states on the designer surface, you must add activities to the states.

    States support the following activities:

    • StateActivity

    • EventDrivenActivity

    • StateInitializationActivity

    • StateFinalizationActivity

    You will work with only the StateInitializationActivity and the EventDrivenActivity.

  8. Select the eventDrivenActivity1 in the ReportInitialState state.

  9. In the Properties window, select the Name property, and rename it to eventInitWorkflow.

  10. Drag a StateInitialization activity to the ReportSubmittedState state. Rename this activity to stateInitReportSubmittedState.

  11. Repeat this for the ReportApprovedState state and the ReportRejectedState state. Rename these to stateInitReportApprovedState and stateInitReportRejectedState respectively.

  12. Drag an EventDriven activity to the ReportSubmittedState. Rename it to eventReviewReport.

    Note

    You cannot drop EventDriven activities above the StateInitialization activity; the designer moves the activity below the StateInitialization activity for you.

    Your workflow designer should look similar to Figure 3.

    Figure 3. Incomplete workflow layout

    Incomplete workflow layout

Now, you fill in the details of each state.

To add Initial state details

  1. To start, double-click the eventInitWorkflow activity in the ReportInitialState state.

    You should see the following.

    Figure 4. Detail view

    Detail view

    You can use the breadcrumb links across the upper-left part of the designer to return to the state view of the workflow.

  2. First, rename the onWorkflowActivated1 activity to onReportWorkflowActivated.

  3. In the Properties window, select the CorrelationToken property. In the drop-down list, select workflowToken, if it is not already selected.

  4. Click the plus sign (+) to expand the CorrelationToken property. Select the OwnerActivityName under the CorrelationToken property, and in the drop-down list, select ExpenseReportStateMachineWorkflow, if it is not already selected.

  5. Select the WorkflowProperties property, and on the far right, click the ellipsis (…) button.In the

  6. Binding dialog box, select the Bind to an existing member tab.Select workflowProperties, and then click OK.

  7. The last thing you need to do is right-click the onReportWorkflowActivated activity, and then select Generate Handlers. This takes you to the code-behind class, to an autogenerated method stub. Return to the designer.

  8. Drag a CreateTask activity under the onReportWorkflowActivated activity. Rename it to createReportTask.

  9. In the Properties window, select the CorrelationToken property, and type taskToken.

  10. Click the plus sign (+) to expand the CorrelationToken property. Select the OwnerActivityName beneath the CorrelationToken property, and in the drop-down list, select ExpenseReportStateMachineWorkflow.

  11. Select the TaskId property, and then click the ellipsis (…) button on the far right.

  12. In the Binding dialog box, select the Bind to a new member tab. Type taskId. Select the Create Field option, and click OK.

  13. Next, select the TaskProperties property, and click the ellipsis (…) button on the far right. In the Binding dialog box, select the Bind to a new member tab.

  14. Type taskProperties. Select the Create Field option, and click OK.

  15. The last thing you have to do for this is right-click the createReportTask activity, and select Generate Handlers. This takes you to the code-behind class, to an autogenerated method stub. Return to the designer.

  16. Drag a SetState activity beneath the createReportTask activity.

    Note

    There are two SetState activities that are included with Visual Studio 2008. In this example, you only use the SetState activity in the Windows Workflow v3.0 Toolbox category.

  17. Rename this to setStateSubmitted.

  18. Select the TargetStateName property, and in the drop-down list, select ReportSubmittedState.

  19. In the upper-left corner, click the ExpenseReportStateMachineWorkflow link to return to the State view.

To add Submitted state details

  1. Double-click the stateInitReportSubmittedState activity in the ReportSubmittedState to open the detail view of this activity.

  2. Drag a LogToHistoryListActivity activity to the design surface. Rename it to logToHistoryReportSubmittedState.

  3. Right-click logToHistoryReportSubmittedState, and select Generate Handlers. Return to the designer.

  4. Return to the State view.Double-click the eventReviewReport activity in the ReportSubmittedState to open the detail view of this activity.

  5. Drag an onTaskChanged activity to the design surface. Rename it to onTaskChangedReportReviewed.

  6. In the Properties window, select the CorrelationToken property, and in the drop-down list, select taskToken.

  7. Select the AfterProperties property, and click the ellipsis (…) button at the far right.

  8. In the Binding dialog box, select the Bind to a new member tab.

  9. Type afterProperties. Select the Create Field option, and then click OK.

  10. Repeat Steps 7–9 for the BeforeProperties property, but replace the word "after" with "before."

  11. Select the TaskId property, and click the ellipsis (…) button at the far right.

  12. In the Binding dialog box, the Bind to an existing member tab should be selected. If it is not selected, select it now, and then select the taskId property that you created earlier. Click OK.

  13. Right-click onTaskChangedReportReviewed, and then select Generate Handlers. This takes you to the code-behind class. Return to the designer.

  14. Now drag an IfElse activity underneath the onTaskChangedReportReviewed activity. Rename it to ifElseReportReview.

  15. Rename the first ifElseBranch to ifElseReportApproved.

  16. In the Properties window, select the Condition property. In the drop-down list, select Code Condition.

  17. Expand the Condition property. There is a sub-property also named Condition. Type IsReportApproved, and then press ENTER.

  18. This opens the code behind class, which contains a method stub for IsReportApproved. Return to the designer.

  19. Rename the second ifElseBranch to ifElseReportRejected.In the

  20. Properties window, select the Condition property. In the drop-down list, select Code Condition.

  21. Expand the Condition property. There is a sub-property also named Condition. Type IsReportRejected, and then press ENTER.

    Again, you are taken to the code-behind class. Return to the designer.

  22. Now, drag a SetState activity onto the ifElseReportApproved activity.

    Rename it to setStateReportApproved.

  23. In the Properties window, select the TargetStateName property, and in the drop-down list, select ReportApprovedState.

  24. Drag a SetState activity onto the ifElseReportRejected activity, and rename it to setStateReportRejected.

  25. Select the TargetStateName property, and in the drop-down list, select ReportRejectedState.

  26. Click the ExpenseReportStateMachineWorkflow link in the upper–left corner to return to the State view.

To add Approved state and Rejected state details

  1. Double-click the stateInitApprovedState activity in the ReportApprovedState state.

  2. Drag a LogToHistoryListActivity activity to the design surface, and rename it to logToHistoryReportApprovedState.

  3. Right-click logToHistoryReportApprovedState, and select Generate Handlers. Return to the designer.

  4. Drag a CompleteTask activity below the logToHistoryReportApprovedState activity. Rename it to completeTaskReportApproved.

  5. In the Properties window, select the CorrelationToken property, and in the drop-down list, select taskToken.

  6. Select the TaskId property, and then click the ellipsis (…) button at the far right.

  7. In the Binding dialog box, the Bind to an existing member tab should be selected for you. If it is not selected, select it now. Select the taskId property that you created earlier, and then click OK.

  8. Right-click completeTaskReportApproved, and select Generate Handlers. Return to the designer.

  9. Drag a SetState activity under the completeTaskReportApproved activity. Rename it to setStateReportApprovedComplete.

  10. Select the TargetStateName property, and in the drop-down list, select ReportCompleteState.

    Repeat these same steps for the ReportRejectedState, replacing the word "Approved" with "rejected." When you are finished, your workflow should look like the following figure.

    Figure 5. Complete workflow layout

    Complete workflow layout

Adding Code to the Workflow

Now that you have designed your workflow, you must add code to provide the logic.

To add code to the workflow

  1. Add your own fields, as follows.

  2. Add properties for each field. You do not have to provide setters; getters are sufficient.

    Add some code to your onReportWorkflowActivated_Invoked method, as follows.

    Note

    The Domain field was added to the Expense Report form. For information about modifying the InfoPath Expense Report form see the Visual How To, Creating a Custom Approval Workflow for SharePoint Server 2007 Using SharePoint Designer 2007.

  3. Next, add code to the createReportTask_MethodInvoking method, as shown here.

  4. Add code to the onTaskChangedReportReviewed_Invoked method.

  5. Next, code the logic methods. Add the following code to the IsReportRejected method.

  6. Add the following code to the IsReportApproved method.

  7. Add the following code to the completeTaskReportApproved_MethodInvoking and the completeTaskReportRejected_MethodInvoking methods.

  8. Next, add your logging code. Add the following code to the logToHistoryReportSubmittedState_MethodInvoking method.

  9. Repeat these steps for the logToHistroyReportApprovedState_MethodInvoking and logToHistoryReportRejectedState_MethodInvoking methods. Change the text to "Report Approved" and "Report Rejected" respectively.

Updating the Workflow.xml File

Next, you must make sure that the Workflow.xml file is updated to include your Expense Report Approval task form.

To update Workflow.xml

  1. Add the following element as a child to the MetaData element.

  2. Replace the URN above with the URN from your Expense Report Approval task form. To find the URN of an InfoPath form, open the form in design view. Click File, and then click Properties. The URN is in the ID text box.

  3. Add the TaskListContentTypeId attribute to the Workflow element.

    Note

    It is critical that you type this number exactly as shown. If your task form does not show up, verify whether this number is correct.

  4. Update the CodeBesideClass attribute from the default value of ExpenseReportStateMachineWF.workflow1 to ExpenseReportStateMachineWF.ExpenseReportStateMachineWorkflow.

Updating the Feature.xml File

Next, you must ensure that the Feature.xml file is updated to include the Expense Report Approval task form.

To update Feature.xml

  1. Add the following element as a child to the ElementManifests element.

Running the Workflow Project from Visual Studio 2008

All you have to do now is press F5 and run your project. Visual Studio 2008 lets you debug your workflows by placing breakpoints in code. Visual Studio 2008 also handles the details of deploying your workflow to SharePoint Server. You may still need to manually add the workflow to your Document Library in Office SharePoint Server.

Figure 6. Build Output

Build output Read It

State machine workflows enable you to model real-world events and business processes. Visual Studio 2008 makes creating and debugging these workflows easier than ever. Visual Studio also gives you the ability to package your workflow features and deploy them easily. For more information see Configuring and Deploying Workflows to SharePoint Server 2007 Using Solution Packages.

See It Building State Machine Document Approval Workflows

Watch the Video

Video Length: 00:07:11

File Size: 16.3 MB WMV

Explore It