Microsoft Virtual Labs

®

A SharePoint Developer Introduction - Workflow C#

A SharePoint Developer Introduction - Workflow C#

Table of Contents
A SharePoint Developer Introduction - Workflow C# .............................................................. 1
Exercise 1 Adding a Workflow to a Document Library ................................................................................................2 Exercise 2 Adding a Workflow to a Calendar ............................................................................................................. 17 Exercise 3 Modifying a Workflow .............................................................................................................................. 27

A SharePoint Developer Introduction - Workflow C#

A SharePoint Developer Introduction Workflow C#
Objectives
After completing this lab, you will be better able to: Build a simple workflow that sends an email when a user adds a document to a document library Build a workflow that creates a task when a user adds a meeting request to a calendar Modify a workflow to send the administrator a reminder email if a period of time has passed without a resolution to the meeting request In this lab, you will explore how to build workflows that perform actions when users take actions in SharePoint. First, you will send an email when a user submits a help request. You will then create an administrator task when a user adds a meeting request to a calendar. Finally, you will then add a process to send a reminder email to the administrator if a period of time passes without resolution to the meeting request. 90 Minutes

Scenario

Estimated Time to Complete This Lab Computers used in this Lab

WSS

Page 1 of 31

A SharePoint Developer Introduction - Workflow C#

Exercise 1 Adding a Workflow to a Document Library
Scenario
In this exercise, you will create a workflow that sends an e-mail when a user creates a new help request document and uploads it to a document library. The help request document contains properties for email alias, date, priority level, issue and notes. You will create a content type that defines fields for each of these properties. You will add the content type on the document library. When the user uploads a help request document, SharePoint will populate the fields with the document’s properties and start the workflow. The workflow will read the fields and include the information in the email. Tasks Complete the following tasks on: WSS Create the workflow project Detailed Steps a. Open Visual Studio 2008 by going to Start Menu | All Programs | Microsoft Visual Studio 2008 | Microsoft Visual Studio 2008. b. In Visual Studio, select File | New | Project. c. The New Project dialog window will display. d. In the New Project dialog window under the Project Types selection select Other Project Types | Visual Studio Solutions. Under the Templates section select Blank Solution. e. Name the solution WSSHOL_HelpRequestWorkflow. f. Enter “C:\SPHOLS\Labs\Lab 04 - Workflow” for the Location. g. Click OK. h. In the Solution Explorer right click the solution and select Add | New Project. i. From the Office | 2007 project type, select SharePoint 2007 Sequential Workflow. Name the project HelpRequestWorkflow.

1.

j. k.

l.

Click OK. In the New Office SharePoint Workflow dialog leave the name as HelpRequestWorkflow and change the local site to use for debugging to http://spvm. Click Next >.

Page 2 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps m. Untick Automatically associate workflow. n. Click Finish. o. In the Solution Explorer, double-click on Workflow1.cs to open the Workflow designer. Note: The workflow contains an OnWorkflowActivated activity by default. Every SharePoint workflow must include this activity as its first activity. p. Drag a SendEmail activity from the Toolbox to the workflow below onWorkflowActivated1. q. Click the red circle with the exclamation mark to see the error message.

Note: A correlation token is an identifier used by the Windows Workflow Foundation runtime to keep track of multiple instances of a workflow. When SharePoint starts this workflow, the workflow runtime will first check if an instance of the workflow is already running. If it is, the workflow runtime will reuse the existing workflow, rather than start a second instance. This provides better performance. In order to process any given instance of the SendEmail activity, the workflow runtime needs to know to which instance of the workflow the activity instance belongs. r. Select onWorkflowActivated1. s. In the Properties window, expand the CorrelationToken property. Note: When the workflow begins, the OnWorkflowActivated activity executes first. The workflow runtime creates a correlation token, represented by workflowToken. This token is unique to this instance of the workflow. You can assign sendEmail1 a correlation token of workflowToken to specify that a particular instance of that activity belongs to a particular instance of the workflow. t. Select sendEmail1. u. Select workflowToken from the drop-down list associated with the CorrelationToken property. v. Double-click the sendEmail1 activity. w. Visual Studio creates the sendEmail1_MethodInvoking method and opens the code editor. Note: Visual Studio automatically adds the following code to the workflow’s code file:
public Guid workflowId = default(System.Guid); public Microsoft.SharePoint.Workflow.SPWorkflowActivationPropertie s workflowProperties = new Microsoft.SharePoint.Workflow.SPWorkflowActivationPropertie s();

Page 3 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps x. Add the following code to the sendEmail1_MethodInvoking method:
System.Collections.Hashtable collHashes = this.workflowProperties.Item.Properties; System.Collections.ICollection collKeys = collHashes.Keys;

Note: This code retrieves the properties of the Help Request document. The workflow will check if the document uploaded to the library is really a help request. If it is, the EmployeeAlias, Priority, Issue and Notes properties will exist. y. Add the following code to the sendEmail1_MethodInvoking method:
string string string string employeeAlias = string.Empty; priority = string.Empty; issue = string.Empty; notes = string.Empty;

Note: This code creates fields to store the values of the four document properties that describe the help request. This information will be included in the body of the email. z. Add the following code to the sendEmail1_MethodInvoking method:
foreach (object oKey in collKeys) { if (oKey.ToString() == "EmployeeAlias") { employeeAlias = collHashes[oKey.ToString()].ToString(); } if (oKey.ToString() == "UserPriority") { priority = Convert.ToDouble(collHashes[ oKey.ToString()].ToString()).ToString(); } if (oKey.ToString() == "Issue") { issue = collHashes[oKey.ToString()].ToString(); } if (oKey.ToString() == "Notes1") { notes = collHashes[oKey.ToString()].ToString(); } }

Note: This code loops through all of the document properties. It stores the four properties we are interested in to the appropriate fields. aa. Add the following code to the sendEmail1_MethodInvoking method:
sendEmail1.To = "administrator@sharepoint.local"; sendEmail1.Subject = "New help request";

bb. Add the following code to the sendEmail1_MethodInvoking method:
System.IO.StringWriter mailBody = new System.IO.StringWriter(); mailBody.WriteLine(string.Format( "The following was received today ({0:d})", DateTime.Today)); mailBody.WriteLine();

Note: The code uses a StringWriter to create the body of the email. cc. Add the following code to the sendEmail1_MethodInvoking method:

Page 4 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps
if (employeeAlias == string.Empty || priority == string.Empty || issue == string.Empty || notes == string.Empty) { mailBody.WriteLine("The document {0} was uploaded", this.workflowProperties.Item.Name); mailBody.WriteLine(); mailBody.WriteLine("It is not a valid help request document."); }

Note: If the document does not have these four properties, it is not a valid help request. In that case, the workflow sends an email to that effect. The administrator can retrieve the document and decide how to proceed. dd. Add the following code to the sendEmail1_MethodInvoking method:
else { mailBody.WriteLine("From: " + employeeAlias); mailBody.WriteLine(); mailBody.WriteLine("Priority: " + priority); mailBody.WriteLine(); mailBody.WriteLine(); mailBody.WriteLine("Issue: " + issue); mailBody.WriteLine(); mailBody.WriteLine("Notes: " + notes); mailBody.WriteLine(); mailBody.WriteLine(); mailBody.WriteLine("See : " + this.workflowProperties.Item.Name); }

Note: If the document is a valid help request, add to the email the information contained in the document's properties. ee. Add the following code to the sendEmail1_MethodInvoking method: sendEmail1.Body = mailBody.ToString(); Note: This code adds the string you have just built to the body of the email message ff. Remove the Microsoft.Office.Workflow.Utility namespace reference at the top of Workflow1.cs:
//using Microsoft.Office.Workflow.Utility;

Note: Before you deploy this workflow to SharePoint, you must strong name the assembly. gg. From the menu, select Project | HelpRequestWorkflow Properties. hh. Visual Studio displays the Project Designer. ii. In the Project Designer, select the Signing page. jj. In the Signing page, make sure Sign the assembly is checked. kk. From the Choose a strong name key file drop-down list, select New. ll. Visual Studio displays the Create Strong Name Key dialog window. mm. In the Create Strong Name Key dialog window, enter HelpRequestWorkflowKey in the Key file name textbox. nn. Uncheck Protect my key file with a password and click OK. oo. Close the Project Designer.

Page 5 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps pp. Save and build the solution. qq. Bring up a Visual Studio Command Prompt (beneath Visual Studio Tools on the start menu). rr. Change to the projects output directory (which should be C:\SPHOLS\Labs\Lab 04 Workflow\WSSHOL_HelpRequestWorkflow\HelpRequestWorkFlow\bin\Debug) ss. Type sn -T HelpRequestWorkflow.dll and copy the public key token to the clipboard. tt. Next open the workflow.xml file and locate the CodeBesideAssembly attribute. Replace the public key token with the one from the clipboard. uu. Open feature.xml and remove the ReceiverAssembly and ReceiverClass attributes. vv. Save all files and build. Note: You are now ready to deploy the workflow to SharePoint. To do this, you can use the following files: feature.xml. You use this file to package the workflow as a SharePoint feature. Features are a convenient way of deploying SharePoint solutions, such as workflows, Web Parts, site definitions, etc. Visual Studio created this file and added it to the project. workflow.xml. This file defines the workflow and contains the information SharePoint needs to instantiate and run the workflow. Visual Studio created this file and added it to the project. contenttype.xml. This file defines the content type containing the email alias, date, priority level, issue and notes fields. You will create this file and add it to the project. a. In the Solution Explorer, double-click feature.xml. b. Add the following XML element inside the <ElementManifests> element. <ElementManifest Location="contenttype.xml" /> Note: The feature.xml file defines the feature and contains references to the objects packaged in the feature. The Feature element defines a feature and to specifies the location of assemblies, files, dependencies, or properties that support the feature. The Id attribute uniquely identifies the feature. The Title and Description attributes display in SharePoint. For a workflow, the Scope attribute must be set to Site. The ElementManifests element contains references to the file or files that define the elements of the feature. In this example, you will use the file workflow.xml to define the workflow and the file contenttype.xml to define the contenttype. c. In the Solution Explorer, right-click on HelpRequestWorkflow and select Add | Existing Item from the menu. d. The Add Existing Item - HelpRequestWorkflow dialog window will display. e. In the Add Existing Item - HelpRequestWorkflow dialog window, navigate to the C:\SPHOLS\Labs\Lab04_Workflow\Resources\Lab 1 folder. f. Select the file contenttype.xml and click Add. g. In the Solution Explorer, double-click contenttype.xml. h. The file contains the following XML:

2.

Deploy the workflow to SharePoint

Page 6 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps
<?xml version="1.0" encoding="utf-8" ?> <Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <!-- Define the Help Request content type --> <Field ID="{C6F07C5F-823A-42a3-B31A-29C9E4332D52}" Name="EmployeeAlias" DisplayName="Alias" Type="Text" Group="HelpRequest" /> <Field ID="{DCCADD9E-F8A1-4f60-ABEE-7422D17B6DBE}" Name="RequestDate" DisplayName="Date" Type="DateTime" Group="HelpRequest" /> <Field ID="{A55A5AAA-123B-4263-8D63-785F31D93895}" Name="Issue" DisplayName="Issue" Type="Text" Group="HelpRequest" /> <Field ID="{46833A1B-0CDA-4ee4-92E2-64843638841E}" Name="UserPriority" DisplayName="Priority" Type="Number" Group="HelpRequest" /> <Field ID="{A17F2592-9FC4-41ec-AC96-FD092F3F0AFA}" Name="Request Notes" DisplayName="Request Notes" Type="Note" Group="HelpRequest" /> <ContentType ID="0x010100773D844FEC7E44b895CA0E23678CA995" Name="Help Request" Group="Support" Description="Help Request Details" > <FieldRefs> <FieldRef ID="{C6F07C5F-823A-42a3-B31A-29C9E4332D52}" Name="EmployeeAlias" Required="TRUE" /> <FieldRef ID="{DCCADD9E-F8A1-4f60-ABEE-7422D17B6DBE}" Name="RequestDate" Required="TRUE" /> <FieldRef ID="{A55A5AAA-123B-4263-8D63-785F31D93895}" Name="Issue" Required="TRUE" /> <FieldRef ID="{46833A1B-0CDA-4ee4-92E2-64843638841E}" Name="UserPriority" Required="TRUE" /> <FieldRef ID="{A17F2592-9FC4-41ec-AC96-FD092F3F0AFA}" Name="Request Notes" Required="TRUE" /> </FieldRefs> </ContentType> </Elements>

Note: The contenttype.xml file defines the content type and the fields included in the content type. The Field element defines a site column, or field. The ID attribute uniquely identifies the column. The Name and Description attributes will display in SharePoint. The Type attribute describes the data type of the column. The Group attribute specifies the site column group to which the column belongs. The ContentType element defines a content type. The ID attribute uniquely identifies the content type. The Name and Description attributes will display in SharePoint. The Group attribute specifies the content type group to which the content type belongs. The FieldRefs element contains a collection of FieldRef elements. The FieldRef element is a reference to a column defined elsewhere, either at the site or list level. The ID attribute uniquely identifies the field. The Name attribute will display in SharePoint. The Required attribute identifies that these fields are required.

Page 7 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps i. In the Solution Explorer, right-click on HelpRequestWorkflow and select Add | Existing Item from the menu. j. The Add Existing Item - HelpRequestWorkflow dialog window will display. k. In the Add Existing Item - HelpRequestWorkflow dialog window, navigate to the C:\SPHOLS\Labs\Lab04_Workflow\Resources\Lab 1 folder. l. Select the file Install.bat and click Add. m. In the Solution Explorer, double-click Install.bat. n. The file contains the following:
echo Copying the feature... rd /s /q "%CommonProgramFiles%\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\HelpRequestWorkflow" mkdir "%CommonProgramFiles%\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\HelpRequestWorkflow" copy /Y feature.xml "%CommonProgramFiles%\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\HelpRequestWorkflow\" copy /Y workflow.xml "%CommonProgramFiles%\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\HelpRequestWorkflow\" copy /Y contenttype.xml "%CommonProgramFiles%\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\HelpRequestWorkflow\" xcopy /s /Y *.aspx "%programfiles%\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\LAYOUTS" echo Adding assemblies to the GAC... "%programfiles%\Microsoft SDKs\Windows\v6.0A\Bin\gacutil.exe" -uf HelpRequestWorkflow "%programfiles%\Microsoft SDKs\Windows\v6.0A\Bin\gacutil.exe" -if bin\Debug\HelpRequestWorkflow.dll :: Note: 64-bit alternative to lines above; uncomment these to install on a 64-bit machine ::"%programfiles% (x86)\Microsoft SDKs\Windows\v6.0A\Bin\gacutil.exe" -uf HelpRequestWorkflow ::"%programfiles% (x86)\ Microsoft SDKs\Windows\v6.0A\Bin\gacutil.exe" -if bin\Debug\HelpRequestWorkflow.dll

echo Activating the feature... pushd %programfiles%\common files\microsoft shared\web server extensions\12\bin ::Note: Uncomment these lines if you've modified your deployment xml files or IP forms ::stsadm -o deactivatefeature -filename HelpRequestWorkflow\feature.xml -url http://spvm

Page 8 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps
::stsadm -o uninstallfeature -filename HelpRequestWorkflow\feature.xml stsadm -o installfeature -filename HelpRequestWorkflow\feature.xml -force stsadm -o activatefeature -filename HelpRequestWorkflow\feature.xml -url http://spvm

echo Doing an iisreset... popd iisreset

Note: The install.bat file copies the required files to a directory on the SharePoint server, adds the workflow assembly to the Global Assembly Cache, installs and activates the feature on SharePoint and resets IIS so the new feature is recognized. o. p. q. Open a command prompt by going to Start Menu | Command Prompt. In the command prompt, navigate to C:\SPHOLS\Labs\Lab 04 Workflow\WSSHOL_HelpRequestWorkflow\HelpRequestWorkflow. Type install to install the HelpRequestWorkflow feature.

r. Type exit to close the command prompt.

Page 9 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps

Page 10 of 31

A SharePoint Developer Introduction - Workflow C# Tasks 3. Associate the workflow with the document library Detailed Steps a. b. In Internet Explorer, browse to http://spvm. From the SharePoint home page select Site Actions | Site Settings.

c.

Under the Site Collection Administration section, select Site Collection Features.

Note: Confirm that the Help Request Workflow feature is now installed and active. d. In the upper left of the Web page, select the Home tab to return to the Team Site home page. e. In the Documents list, select Shared Documents. f. From the Shared Documents page select Settings | Document Library Settings.

g. h. i. j.

In the General Settings section, select Advanced settings. Ensure Allow management of content types? is set to Yes. Click OK. In the Content Types section, select Add from existing site content types.

k. The Add Content Types page displays.

Page 11 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps l. In the Select content types from drop-down list, select Support. m. In the Available Site Content Types list, select Help Request and click Add. n. Click OK.

o. On the Customize Shared Documents page, select Change new button order and default content type. p. The Change New Button Order and Default Content Type page displays. q. From the Help Request content type’s Position from Top drop-down list, select 1. i. Click OK.

r. At the top of the Web page, select the Shared Documents link. s. Click New -> | Help Request to create a new instance of the Word document. We will use this to create a template based off of our content type. t. At the top of the document type in Order Request Template (16pt Bold) u. Next click on the insert menu and insert a 2 column 5 row table. v. In the left column add all of the column names that you see in the document information panel: Alias, Date, Issue, Priority, Request Notes. w. In the right column we will want to add a Word “Quick Part” that will allow us to synch the fields in Word with the meta data columns on the server. Fill in all of the document information panel fields with “test” data then save the document back to the Document Library.

Page 12 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps

x. Re-Open the document out of the Document Library. y. To add a Quick Part, place your cursor in the first column on the right. On the insert menu go to Quick Parts -> | Document Properties and add the field for each corresponding column (remove the test data from the document information panel at the top because we won’t need it within the template). z. Your form should look similar to this:

aa. Click the Office button | Save As -> | Word Template. Name the file Help Request.dotx and save it to the following directory: C:\SPHOLS\ Lab04_Workflow\Resources\Lab 1. Delete the existing file in the document library. bb. Select Site Actions | Site Settings at the top of the page to return to the Site Settings page. cc. Under the Galleries section, select Site Content Types. dd. The Site Content Type Gallery page displays. ee. Under the Support section, select Help Request. ff. The Site Content Type: Help Request page displays. gg. Under the Settings section, select Advanced Settings. hh. The Site Content Type Advanced Settings page will display. ii. Select Upload a new document template. jj. Click Browse. The Choose file dialog window will display. kk. In the Choose file dialog window, navigate to the C:\SPHOLS\Labs\Lab04_Workflow\Resources\Lab 1 folder. ll. Select the Help Request.dotx file and click Open. mm. On the Site Content Type Advanced Settings page, click OK. nn. On the Site Content Type page, under the Settings section, select Workflow Settings. oo. The Change Workflow Settings page will display. pp. Click Add a workflow. The Add a Workflow page will display. Page 13 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps qq. The Add a Workflow page will display.

rr. Select Help Request Workflow in the Select a workflow template list. ss. Enter Help Request Workflow in the unique name text box. tt. Check Start this workflow when a new item is created. uu. Click OK. 4. Submit a help request and start the workflow Note: You are now ready to submit a help request document and test the workflow. a. At the top of the Web page, select the Home link to SharePoint home page. b. Select the Shared Documents link from the Quick Launch menu. c. Select New | Help Request.

Page 14 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps d. Internet Explorer displays a security message. Click OK to dismiss the message. e. Word starts and creates a new document from the Help Request template. f. Enter maria.anders for the employee alias. g. Set the request date to today’s date. h. Leave the priority set to 2. i. Enter Need bigger monitor as the issue. j. Enter I do a lot of development and I need a 24 inch flat display please as the notes.

k. Click the Save button in the Quick Access Toolbar. l. Word displays the Save As dialog window. m. Name the document Maria Anders – Monitor.docx. n. Click Save in the Save As dialog window to save the document in the Shared Documents document library o. Close Word. p. SharePoint displays the document in the Shared Documents document library. It also displays that the Help Request Workflow completed. q. Open Outlook Express by going to Start Menu | Programs | Outlook Express. r. Navigate to the Inbox. s. Open the New help request mail.

Page 15 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps t. Close the mail message. u. Exit Outlook Express.

Page 16 of 31

A SharePoint Developer Introduction - Workflow C#

Exercise 2 Adding a Workflow to a Calendar
Scenario
In this exercise, you will create a workflow and attach it to a calendar. When a user adds a meeting request to the calendar, a workflow begins. The workflow marks the meeting request as tentative and creates a task, assigning it to the administrator. If the administrator marks the task as complete, the meeting request is accepted and the workflow will mark it as so. If the administrator deletes the task without completing it, the workflow will remove the meeting request from the calendar. Tasks Complete the following tasks on: WSS Create the workflow project Detailed Steps a. Open Visual Studio 2008 by going to Start Menu | Programs | Microsoft Visual Studio 2008 | Microsoft Visual Studio 2008. b. In Visual Studio, select File | New | Project. c. The New Project dialog window will display. d. In the New Project dialog window under the Project Types selection select Other Project Types | Visual Studio Solutions. Under the Templates section select Blank Solution. e. Name the solution WSSHOL_MeetingRequestWorkflow. f. Enter “C:\SPHOLS\Labs\Lab 04 - Workflow” for the Location. g. Click OK. h. In the Solution Explorer right-click the solution and select Add | New Project. i. From the Office | 2007 project type, select SharePoint 2007 Sequential Workflow. j. Name the project MeetingRequestWorkflow. k. Click OK. l. In the New Office SharePoint Workflow dialog leave the name as MeetingRequestWorkflow and change the local site to use for debugging to http://spvm. m. Click Next . n. Untick Automatically associate workflow. o. Click Finish. p. In the Solution Explorer, double-click on Workflow1.cs to open the Workflow designer. a. Drag a CreateTask activity from the Toolbox to the workflow below onWorkflowActivated1. Note: Before you can specify such things as the task’s title, due date and who it is assigned to, you need to take three steps when working with a task in a workflow. First, you need to create a correlation token for the task. This correlation token should be different from the workflow’s token. Additional activities in the workflow that work with the task will share the task’s correlation token. Secondly, you need to assign a GUID to the task and set the CreateTask activity’s TaskId property to it. Finally, you need to create a task properties object and set the CreateTask activity’s TaskProperties property to it. The task properties object you create will be an instance of the SPWorkflowTaskProperties class. That class provides you access to task properties such as Title, AssignedTo, DueDate and Description. You can use the

1.

2.

Create a task

Page 17 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps ExtendedProperties property of this class to access additional information in the task. For example, you can use this if you want to know the value of the task’s Status property.

Select createTask1. Enter taskToken in the CorrelationToken property. Expand the CorrelationToken property. In the drop-down list associated with the OwnerActivityName property, select Workflow1. f. Click the ellipsis associated with the TaskId property. g. Visual Studio displays the Bind ‘TaskId’ to an activity’s property dialog window. h. In the Bind ‘TaskId’ to an activity’s property dialog window, select the Bind to a new member tab. i. Select Create Field. j. Name the field taskId. k. Click OK to dismiss the dialog window. l. Click the ellipsis associated with the TaskProperties property. m. Visual Studio displays the Bind ‘TaskProperties’ to an activity’s property dialog window. n. In the Bind ‘TaskProperties’ to an activity’s property dialog window, select the Bind to a new member tab. o. Select Create Field. p. Name the field taskProperties. q. Click OK to dismiss the dialog window.

b. c. d. e.

Page 18 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps

r.

From the menu, select View | Code to switch to the workflow’s code file. Visual Studio automatically added the following code to the workflow’s code file:
public Guid workflowId = default(System.Guid); public Microsoft.SharePoint.Workflow.SPWorkflowActivationProperti es workflowProperties = new Microsoft.SharePoint.Workflow.SPWorkflowActivationProperti es(); public Guid taskId = default(System.Guid); public Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties taskProperties = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();

s. t. u.

From the menu, select View | Designer to switch back to the workflow designer. Double-click the createTask1 activity. Visual Studio creates the createTask1_MethodInvoking method and opens the code editor. Note: The createTask1_MethodInvoking method executes before the workflow creates the task. It is therefore the right place to set properties of the task. v. Add the following code to the createTask1_MethodInvoking method:

Page 19 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps
taskId = Guid.NewGuid(); taskProperties.Title = "Approve Meeting Request"; taskProperties.AssignedTo = @"spvm\Administrator"; taskProperties.DueDate=DateTime.Today; taskProperties.Description = string.Format("{0} requested {1}", this.workflowProperties.Originator, this.workflowProperties.Item.Name);

Note: The TaskId property of the CreateTask activity is bound to the tasked field. By creating a new Guid and assigning it to the taskId field, this code sets the GUID of the task. The code then sets the title of the task and assigns it to the Administrator. The due date of the task is set to today. The task description alerts the administrator that a user requested a meeting. The user is the person who added the meeting request that started the workflow. The code uses workflowProperties.Originator to determine who requested the meeting. The meeting is the item that started the workflow and the code uses workflowProperties.Item to reference the meeting. w. Add the following code to the createTask1_MethodInvoking method:
this.workflowProperties.Item["Title"] = "Tentative - " + Convert.ToString(this.workflowProperties.Item["Title"]); this.workflowProperties.Item.Update();

Note: This code renames the meeting request, indicating that it is tentative pending the approval of the administrator. 3. Listen for task completion or deletion Note: After the workflow creates the task, it will wait for the administrator to make update or delete the task. You will use an OnTaskChanged activity to alert the workflow that the administrator modified the task. You will then check if the administrator marked the task as completed and therefore approved the meeting request. You will then delete the completed task. You will use an OnTaskDeleted activity to alert the workflow that the administrator deleted the task and therefore rejected the meeting request. a. Select View | Designer to return to the workflow designer. b. Drag a Listen activity from the Toolbox to the workflow below createTask1. The Listen activity is under the Windows Workflow v3.0 section. c. Drag an OnTaskChanged activity from the Toolbox into the left branch of the Listen activity. d. Drag an OnTaskDeleted activity from the Toolbox into the right branch of the Listen activity.

Page 20 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps

Note: The workflow needs to know that these activities are associated with the task created in the previous workflow step. In other words, it needs to know that what task has been updated or deleted. e. Select onTaskChanged1. f. From the drop-down list associated with the CorrelationToken property, select taskToken. g. Click the ellipsis associated with the TaskId property. h. Visual Studio displays the Bind ‘TaskId’ to an activity’s property dialog window. i. In the Bind ‘TaskId’ to an activity’s property dialog window, select taskId and click OK. Note: Next, you will write code that executes when the administrator completes or deletes the task. j. k. Double-click the onTaskChanged1 activity. Visual Studio creates the onTaskChanged1_Invoked method and opens the code editor.
Guid statusGuid = workflowProperties.TaskList.Fields["Status"].Id; if (Convert.ToString(taskProperties.ExtendedProperties[status

l. Add the following code to the onTaskChanged1_Invoked method:

Page 21 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps
Guid]) == "Completed") { }

Note: When the task has changed, this code will execute. The task could change for many reasons. The administrator may have added notes to it, changed the due date, or increased the percent completed from 20% to 50%. This workflow takes no actions unless the administrator has marked the task as complete. For the purposes of this exercise, that constitutes approval of the meeting request. In this code, you want to read the value of the Status property of the task. That is not a property of the SPWorkflowTaskProperties class. However, you can access it through the ExtendedProperties property by first finding the GUID of the Status property. m. Add the following code to the if block in the onTaskChanged1_Invoked method:
// Remove the tentative descriptor from the meeting if (Convert.ToString(this.workflowProperties.Item["Title"]). Substring(0, 12) == "Tentative - ") { // Remove the word Tentative from the title this.workflowProperties.Item["Title"] = Convert.ToString( this.workflowProperties.Item["Title"]).Substring(12); // Mark the meeting request as approved this.workflowProperties.Item["Approved"] = 1; // Update the list item this.workflowProperties.Item.Update(); }

n. The meeting request is approved, so this code removes the word Tentative from the title and sets the Approved column to Yes. You will add this column to the Calendar list in Task 4. o. Once the meeting request is approved, the task is no longer needed. You will now add an activity to remove the task. p. Add the following code below the other declarations in the Workflow1 class.
public bool requestResolved = false;

q. Add the following code to the onTaskChanged1_Invoked method:
requestResolved = true;

Note: Add this code inside the outer if statement, but after the inner if statement. r. Select View | Designer. s. Drag an IfElse activity from the Toolbox to the workflow below onTaskChanged1. t. Right click on ifElseActivityBranch2 and select Delete from the menu. u. Select ifElseActivityBranch1. v. Select Declarative Rule Condition from the drop-down list associated with the Condition property.

Page 22 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps w. Expand the Condition property. x. Enter RequestResolved as the ConditionName. y. Click the ellipsis (…) associated with the Expression property. z. Visual Studio displays the Rule Condition Editor dialog window. aa. Enter this.requestResolved in the Rule Condition Editor dialog window. bb. Click OK to close the dialog window.

cc. Drag a DeleteTask activity from the Toolbox to the workflow into ifElseActivityBranch1. dd. Select deleteTask1. ee. From the drop-down list associated with the CorrelationToken property, select taskToken. ff. Click the ellipsis associated with the TaskId property. gg. Visual Studio displays the Bind ‘TaskId’ to an activity’s property dialog window. hh. In the Bind ‘TaskId’ to an activity’s property dialog window, select taskId and click OK. Note: By setting the correlation token to taskToken and setting the task id to taskId, you are informing the workflow which task you want to delete. Next, you will add code to remove the meeting request if the administrator denies it by deleting the task.. ii. Double-click the on TaskDeleted1 activity. jj. Visual Studio creates the onTaskDeleted1_Invoked method and opens the code editor. kk. Add the following code to the onTaskDeleted1_Invoked method:
this.workflowProperties.Item.Delete();

Note: The meeting request has been denied, so the workflow removes the request from the Calendar. ll. Remove the Microsoft.Office.Workflow.Utility namespace reference from the top of the Workflow1.cs file:
using Microsoft.Office.Workflow.Utility;

mm. 4. Deploy the workflow to SharePoint

Save and build the solution.

Note: The steps to deploy this workflow are the same as the steps to deploy the workflow from Exercise 1. Refer to that exercise if you require more detail for each of the following steps. a. In the Solution Explorer, right-click on MeetingRequestWorkflow and select Add | Existing Item from the menu.

Page 23 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps b. The Add Existing Item - MeetingRequestWorkflow dialog window will display. c. In the Add Existing Item - MeetingRequestWorkflow dialog window, navigate to the C:\SPHOLS\Labs\Lab04_Workflow\Resources\Lab 2 folder. d. e. Select Install.bat and click Add. In the Solution Explorer, double-click workflow.xml. Remove the ReceiverAssembly attribute and ReceiverClass attribute from the workflow element.
//ReceiverAssembly="Microsoft.Office.Workflow.Feature, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" ReceiverClass="Microsoft.Office.Workflow.Feature.WorkflowF eatureReceiver"

f. g. h. i. 5. Associate the workflow with the Calendar a. b. c.

Open a command prompt by going to Start Menu | Command Prompt. In the command prompt, navigate to C:\SPHOLS\Labs\Lab 04 Workflow\WSSHOL_MeetingRequestWorkflow\MeetingRequestWorkflow. Type install to install the MeetingRequestWorkflow feature. Type exit to close the command prompt.

In Internet Explorer, browse to http://spvm. From the SharePoint home page select Site Actions | Site Settings. Under the Site Collection Administration section, select Site Collection Features. Note: Confirm that the Meeting Request Workflow feature is installed and active. Your next step is to associate it with the Calendar. d. In the upper left of the Web page, select the Home tab to return to the Team Site home page. e. In the Lists list, select Calendar. f. From the Calendar page, select Settings | List Settings. g. In the Permissions and Management list, select Workflow settings. h. The Add a Workflow page will display. i. Select Meeting Request Workflow in the Select a workflow template list. j. Enter Meeting Request Workflow in the unique name text box. k. Check Start this workflow when a new item is created. l. Click OK. Note: Before you run the workflow, you will first add the Approved column to the Calendar list. a. At the top of the Web page, select the Settings link. b. In the Columns section of the Customize Calendar page, select Create column. c. Enter Approved as the column name. d. Select Yes/No from the list of column types. e. Select No from the Default value drop-down list. f. Click OK. Note: You will now create a meeting request and then set the task to Completed to approve the meeting request. g. At the top of the Web page, select the Calendar link. h. Select New | New Item.

6.

Submit a meeting request and start the workflow

Page 24 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps i. Enter a meeting title, location, start time and end time. Click OK to save the meeting request.

j.

Refresh the Calendar page if necessary to confirm the workflow has changed the title of the meeting to reflect that it is tentative.

k.

On the left of the page, select Tasks from the Lists list.

l. m. n. o. p. q.

Select the Approve Meeting Request task. Click Edit Item. Select Completed from the Status drop-down list. Click OK to save the task. Return to the Calendar and confirm the meeting is no longer tentative. Select the meeting and confirm the Approved column is Yes.

Page 25 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps

Note: When the administrator marks the task as completed, the workflow changes the title of the meeting and sets the Approved column to yes. Of course, anyone with edit rights to the meeting request can do this, so in a production environment, you may choose a more secure way of identifying approved meeting requests. For example, you may copy the meeting to a different calendar to which users do not have edit rights. r. Return to the Tasks list and confirm the workflow deleted the task. Note: You will now create a meeting request and then delete the task to reject the meeting request. s. At the top of the Web page, select the Calendar link. t. Select New | New Item. u. Enter a meeting title, location, start time and end time. Click OK to save the meeting request. v. Refresh the Calendar page if necessary to confirm the workflow has changed the title of the meeting to reflect that it is tentative. w. On the left of the page, select Tasks from the Lists list. x. Select the Approve Meeting Request task. y. Click Delete Item. z. Return to the Calendar and confirm the meeting request is no longer on the calendar.

Page 26 of 31

A SharePoint Developer Introduction - Workflow C#

Exercise 3 Modifying a Workflow
Scenario
In this exercise, you will modify the workflow you created in the previous exercise. Currently, after creating the task, the workflow waits for the administrator to either complete or delete the task. If the administrator does neither, the workflow continues to wait. In this exercise, you will add an activity to send the administrator an email reminding him or her there is a meeting request awaiting approval. The workflow currently performs two actions after creating the task. It waits for the task to be changed and it waits for the task to be deleted. You are going to add a third action to cause the workflow to wait a fixed amount of time and then send a reminder email. You are also going to add a looping activity so that after sending the reminder email, the workflow once again waits for the task to be changed or deleted. If neither of those occurs in the fixed amount of time, the workflow will send the reminder email again. This process will repeat until the task is completed or deleted. To cause the workflow to wait a fixed amount of time, you will add a Delay activity. You will need to work around a known issue where Delay activities do not fire in SharePoint workflows. Tasks Complete the following tasks on: WSS Modify the workflow Detailed Steps Return to Visual Studio. In the Solution Explorer, double-click on Workflow1.cs to open the Workflow designer. c. From the Toolbox, drag a While activity into the workflow between createTask1 and listenActivity1. d. From the Toolbox, drag a Sequence activity into whileActivity1. e. Drag listenActivity1 into sequenceActivity1. f. From the Toolbox, drag a While activity into sequenceActivity1. g. Drag listenActivity1 into whileActivity1. h. Right-click listenActivity1 and select Add Branch from the menu. i. From the Toolbox, drag a Delay activity into eventDrivenActivity3. j. Set the TimeoutDuration property of delayActivity1 to 00:01:00. Note: In a production environment, you would of course not send a reminder email to the administrator every minute, but this will work fine for development purposes. k. From the Toolbox, drag a SendEmail activity into eventDrivenActivity3 below delayActivity1. l. Select sendEmail1. m. From the drop-down list associated with the CorrelationToken property, select workflowToken. a. b.

1.

Page 27 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps

Select whileActivity1. Select Declarative Rule Condition from the drop-down list associated with the Condition property. p. Expand the Condition property. q. Enter RequestNotResolved as the ConditionName. r. Click the ellipsis associated with the Expression property. s. Visual Studio displays the Rule Condition Editor dialog window. t. Enter !this.requestResolved in the Rule Condition Editor dialog window. u. Click OK to close the dialog window. Note: The workflow will continue to listen for the TaskChanged event as long as this condition is true, in other words, as long as the task has not been completed. v. Double-click the sendEmail1 activity. w. Visual Studio creates the sendEmail1_MethodInvoking method and opens the code editor. x. Add the following code to the sendEmail1_MethodInvoking method:

n. o.

Page 28 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps
sendEmail1.To = "administrator@sharepoint.local"; sendEmail1.Subject = "Task reminder"; sendEmail1.Body = "Please resolve this meeting request: " + this.workflowProperties.Item["Title"].ToString();

Note: This email reminds the administrator that there is a meeting request that needs to be resolved. The body of the email includes the meeting name. Remember that the workflow started when the meeting request was added to the Calendar. In this code, this.workflowProperties.Item refers to the meeting, not the task created by the workflow. y. Add the following code to the onTaskDeleted1_Invoked method:
requestResolved = true;

z. 2. Redeploy the workflow

Save and build the solution.

Note: After you make a change to a workflow assembly, you do not need to do a full reinstall. The feature is already installed on SharePoint and activated. The feature is based on an assembly and unless you have changed the fully qualified strong name of the assembly, all you need to do is reinstall the assembly into the Global Assembly Cache. You do not need to make any changes on the SharePoint end. a. In the Solution Explorer, right-click on MeetingRequestWorkflow and select Add | Existing Item from the menu. b. The Add Existing Item - MeetingRequestWorkflow dialog window will display. c. In the Add Existing Item - MeetingRequestWorkflow dialog window, navigate to the C:\SPHOLS\Labs\Lab04_Workflow\Resources\Lab 3 folder. d. Select the reinstall.bat file and click Add. e. In the Solution Explorer, double-click reinstall.bat. Note: The file contains the following:
echo Readding assemblies to the GAC... "%programfiles%\Microsoft SDKs\Windows\v6.0A\Bin\gacutil.exe" -uf MeetingRequestWorkflow "%programfiles%\Microsoft SDKs\Windows\v6.0A\Bin\gacutil.exe" -if bin\Debug\MeetingRequestWorkflow.dll echo Doing an iisreset... popd iisreset

Note: There is an additional step you need to take to fix an issue involving SharePoint workflows and Delay activities. The issue is that when SharePoint executes the Delay activity, the workflow goes to sleep. However, it does not wake up and the workflow will never send the email. To workaround this, you will create and run the following script. f. In the Solution Explorer, right-click on MeetingRequestWorkflow and select Add | Existing Item from the menu. g. The Add Existing Item - MeetingRequestWorkflow dialog window will display. h. In the Add Existing Item - MeetingRequestWorkflow dialog window, navigate to the C:\SPHOLS\Labs\Lab04_Workflow\Resources\Lab 3 folder. i. Select the WorkaroundDelayIssue.bat file and click Add.

Page 29 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps j. In the Solution Explorer, double-click WorkaroundDelayIssue.bat. Note: The file contains the following:
echo Stop SharePoint's Timer Service... net stop SPTimerV3 /Y echo Start SharePoint's Timer Service... net start SPTimerV3 echo Doing an iisreset... popd iisreset

Open a command prompt by going to Start Menu | Command Prompt. In the command prompt, navigate to C:\SPHOLS\Labs\Lab04_Workflow\WSSHOL_MeetingRequestWorkflow\ MeetingRequestWorkflow. m. Type reinstall to reinstall the MeetingRequestWorkflow assembly to the GAC. n. Type workarounddelayissue to shut down and restart the various services. o. Type exit to close the command prompt. 3. Submit a help request and start the workflow In Internet Explorer, browse to http://spvm. On the left of the page, select Calendar from the Lists list. Select New | New Item. Enter a meeting title, location, start time and end time. Click OK to save the meeting request. e. Refresh the Calendar page if necessary to confirm the workflow has changed the title of the meeting to reflect that it is tentative. f. On the left of the page, select Tasks from the Lists list. g. Confirm the workflow has created a task for the administrator. h. Wait several minutes. Note: The Delay activity times out every minute. However, you may find it takes longer than that for the mail to be sent. i. Open Outlook Express by going to Start Menu | Programs | Outlook Express. j. Navigate to the Inbox. k. Open the Task reminder mail. a. b. c. d.

k. l.

l.

Close the mail message.

Page 30 of 31

A SharePoint Developer Introduction - Workflow C# Tasks Detailed Steps m. Wait several additional minutes. n. You should see a second task reminder mail. o. Exit Outlook Express. p. Resolve the workflow by completing or deleting the task.

Page 31 of 31