Chapter 17. Developing workflows

This chapter covers Microsoft SharePoint workflows from a developer perspective, discussing how to create real workflows using either SharePoint Designer 2013 or Microsoft Visual Studio 2012. As you learned in Chapter 16 SharePoint Designer 2013 is a powerful authoring tool for workflows. Whenever you need to create real workflow solutions, consider SharePoint Designer 2013 first. If it does not satisfy your functional requirements, then consider using Visual Studio 2012 instead. You can either design the entire workflow solution within Visual Studio 2012, or you can create custom actions and conditions in Visual Studio while still defining the workflow in SharePoint Designer 2013 (see Chapter 18 for details).

In this chapter, you will learn to create workflows, workflow forms, and SharePoint apps that use workflow features, as well as understand workflow implementation from a practical viewpoint. You’ll begin by using SharePoint Designer.

Consuming REST services

The best way to appreciate the real potential of SharePoint Designer 2013 as a mature workflow authoring tool is to put it to work. In this section, you will use it to create a workflow solution that consumes services via HTTP, as well as Representational State Transfer (REST) and JavaScript Object Notation (JSON). Imagine that you need to create a site workflow that manages all the documents in a library. You can consume the REST API offered by SharePoint 2013 to retrieve the collection of documents, and then you can manage them through the REST API or by using the out-of-the-box activities of SharePoint Designer 2013.

Start SharePoint Designer 2013 and create a new site workflow definition called Documents Maintenance Workflow. Insert a Call HTTP Web Service action, and click the configuration link, which is available in the shape of the action, to access the Call HTTP Web Service dialog box, shown in Figure 17-1.

A screen shot illustrating the dialog window for inserting a Call HTTP Web Service action. It includes a text box for providing the URL of the target HTTP service, as well as a drop-down menu for selecting the HTTP method.

Figure 17-1. The dialog window for configuring the Call HTTP Web Service action of SharePoint Designer 2013.

Choose the HTTP GET request method and provide a URL that retrieves the ID and the Title of all the documents in the library with title Documents. For the example environment, use http://devbook.sp2013.local/sites/Workflows/_api/web/Lists/GetByTitle(’Documents’)/Items?$select=ID,Title.

After defining the HTTP method and the URL, you can configure the request headers, the request body, the response body, the response headers, and the response status code through some dedicated workflow variables. To properly compile the request headers, you add a Build a Dictionary action prior to the Call HTTP Web Service action and configure a variable of type Dictionary to hold the headers’ values, including at least the Accept header for requesting a JSON response format (application/json;odata=verbose). To configure the request headers, right-click the Call HTTP Web Service action and choose the Properties menu. You will be prompted with a dialog box for configuring all the available properties of the Call HTTP Web Service action. There you will find the HTTP RequestHeaders property, as shown in Figure 17-2.

A screen shot showing the properties dialog window for a Call HTTP Web Service action, during the configuration of the RequestHeaders property. It lists all the properties of the Call HTTP web service, which are Address, RequestType, RequestHeaders, RequestContent, ResponseContent, ResponseHeaders, and ResponseCode.

Figure 17-2. The dialog window for configuring the Call HTTP Web Service action during the configuration of the RequestHeaders property.

More Info

As you learned in Chapter 9 the REST API uses the response headers to provide useful information such as the ETag of a single item. Thus, having the capability to collect the response headers of an HTTP request is fundamental in situations when you want to change the items via REST.

The variables for holding these values (request body, request headers, response body, and response headers) must be of type Dictionary, because they will keep a set of values. In particular, consider that the REST service will return JSON content according to the provided Accept request header. An excerpt of the JSON response provided by the REST API while querying the items of a library shows an excerpt of a sample JSON result.

As shown in Figure 17-3, the JSON response has a hierarchical structure.

A diagram depicting the hierarchy of a JSON response retrieved while enumerating all the documents in a library. It shows a root element named d, with a child element named results, which is made of a set of fields nested within the resulting hierarchy.

Figure 17-3. The hierarchical structure of a JSON response retrieved from a REST operation for enumerating the documents of a library.

To manage such a response within the workflow definition, you can use the Get an Item from a Dictionary action. For an input argument, provide the response content retrieved from the Call HTTP Web Service action, and configure the path according to the hierarchy illustrated in Figure 17-3. For example, to retrieve the collection of resulting items, you can provide a path value of d/results. To retrieve a single resulting item, provide a path value of d/results[{Index}], where the {Index} parameter is a numeric indexer.

Now imagine that the goal of the maintenance workflow is to retrieve the title and ID of each document, in order to write them and the number of items retrieved to the workflow history list. To get the number of items, you can use the Count Items in a Dictionary action, providing as input the collection of items (d/result). To extract the ID and the title of every document, simply iterate through them. SharePoint Designer 2013 offers the Loop n Times construct to handle this task. First, retrieve the total number of items returned using the Count Items in a Dictionary action. Then you can loop n times, where the value of n will be the number of retrieved items. Using a local variable to hold the currently selected item index, you can browse all the returned items and retrieve the ID and title of each via a couple of Get an Item from a Dictionary actions. Figure 17-4 illustrates the layout for this workflow.

A screen shot illustrating the workflow definition of a workflow created in SharePoint Designer 2013 for browsing the documents of a library. A unique stage with a set of actions for making the HTTP request against the REST API of SharePoint is followed by a loop for each item in the REST API response, which includes internal steps for incrementing an indexer that enumerates all the responses.

Figure 17-4. The structure of a sample workflow definition for enumerating the documents of a library.

Note that when looping through the resulting items, the Index variable increments in a dedicated inner step. If you save, publish, and execute such a workflow, you will see the workflow status page of the workflow instance, which illustrates the history list with the ID and title of the items retrieved (Figure 17-5).

A screen shot depicting the workflow status page of a completed instance of the sample Documents Maintenance workflow. The image highlights the history list, which enumerates the IDs and titles of all the documents in the target library.

Figure 17-5. The workflow status page of a sample workflow definition.

By using the Call HTTP Web Service action and the other actions to manage dictionaries, you can invoke the native REST API available in SharePoint 2013, targeting your own farm or any other farm, as long as you provide the proper OAuth authentication HTTP headers. As you can see, SharePoint Designer 2013 is a powerful tool for creating workflows, but it’s not the only one.

Visual Studio 2012 for creating workflows

Visual Studio 2012 offers its own advantages for creating workflow definitions. To get started with its creation wizard, launch Visual Studio 2012, create a new project of type SharePoint 2013 - Empty Project and choose to target a farm-level solution. Add a new item to the newly created project by right-clicking the project in Solution Explorer and selecting Add | New Item. Choose a new item of type Workflow, and name it MyFirstWorkflow. A wizard will ask you to provide some information about the workflow you are going to create (Figure 17-6).

A screen shot illustrating the UI of the first step of the wizard for creating a new workflow definition in Visual Studio 2012. You can choose between creating a list workflow or a site workflow.

Figure 17-6. The first step of the wizard for creating a new workflow definition in Visual Studio 2012.

The first step of the wizard asks you to declare if the workflow will target a list or a site. The second step (Figure 17-7) then prompts you to select the target list if you decide to create a list workflow, as well as the target history list and task list. You can also decide to create a new history list and/or new tasks list. In this step, you can also decide whether to associate the workflow definition with a target. Later, during the provisioning of the workflow, you will provide the lists with which you will associate the workflow definition.

A screen shot showing the second step of the wizard for creating a new workflow definition in Visual Studio 2012. It displays fields for configuring the target list, if any, the history list, and the tasks list.

Figure 17-7. The second step of the wizard for creating a new workflow definition in Visual Studio 2012.

The third and last step of the wizard asks you to decide when and how the instances of the workflow definition will be created and started. The available options, as shown in Figure 17-8, are the following:

  • A user manually starts the workflow.

  • The workflow starts automatically when an item is created.

  • The workflow starts automatically when an item is changed.

While developing a new workflow, you should usually choose to manually start the workflow, just because it is easier to debug a workflow and manually start its instances while the debugger is active, rather than having to create or change an item to fire new instances of the workflow definition.

A screen shot depicting the last step of the wizard for creating a new workflow definition in Visual Studio 2012. There are three check boxes to determine how the workflow will be started: manually, upon item creation, or upon item modification.

Figure 17-8. The third and last step of the wizard for creating a new workflow definition in Visual Studio 2012.

Keep in mind that all these options are mainly for debugging purposes. When you create a workflow definition in Visual Studio 2012, the resulting workflow will be available for association wherever you want to associate it. The result of this wizard will be a XAML file, together with a feature element and a SharePoint feature for provisioning the workflow. As you saw in Chapter 15 a XAML workflow file created from scratch is a whiteboard—from a designer viewpoint. Even in this case, by opening the XAML file created, you will have a whiteboard, with just a Sequence activity designed on it. You can now use the toolbox provided by Visual Studio 2012 to define activities on the target design surface. In particular, in the activity toolbox that is available when you are in the designer, you will find many groups of SharePoint-related activities (see Figure 17-9). In Table 17-1, you can see the list of all the SharePoint-related activities available out of the box, divided into functional groups.

A screen shot showing the classic interface of Visual Studio 2012 for designing a new workflow definition from scratch. On the left is a toolbox, which includes several activities. The central area displays the design surface with a previously designed Sequence activity. The classic Solution Explorer and property grid are on the right.

Figure 17-9. The whiteboard for designing workflows in Visual Studio 2012.

Table 17-1. The SharePoint-related activities available in Visual Studio 2012 workflows

Activity name

Description

Group

GetCurrentItemId

Retrieves the ID (Int32) of the current SharePoint list item on which a list workflow instance is running. Returns a value of type Int32.

SP - Current Context

GetHistoryListId

Retrieves the ID of the current SharePoint history list, if a history list is specified in the current workflow association. Returns a value of type GUID.

SP - Current Context

GetTaskListId

Retrieves the ID of the current SharePoint 2013 tasks list, if a tasks list is specified in the current workflow association. Returns a value of type GUID.

SP - Current Context

LookupWorkflowContextProperty

Returns the value of a specified workflow context property. Accepts the context variable name, which can be Associator, Initiator, Association Name, Instance ID, Current Site URL, Current Item URL, List Name, or List ID. Returns a String value.

SP - Current Context

WebUri

Returns the absolute URI of the SPWeb instance containing the currently running workflow instance. Returns a value of type String.

SP - Current Context

CheckInItem

Checks in a list item. Requires the ID of the target list and the ID of the target item. Optionally, also accepts a comment.

SP - List

CheckOutItem

Checks out a list item. Requires the ID of the target list and the ID of the target item.

SP - List

CopyItem

Copies a file item from a source library to a target one. Works only with files, not with simple SharePoint list items. Requires the source list ID, item ID, target list ID, and a flag to allow overwriting the destination.

SP - List

CreateListItem

Creates a SharePoint list item. Requires the target list ID and the target field values as a DynamicValue property. Returns the ID of the created list item, as well as a variable of type DynamicValue with the metadata fields of the just-created list item.

SP - List

DeleteListItem

Deletes a list item. Requires the target list ID and the target list item ID.

SP - List

LookupSPList

Returns, as a DynamicValue, the list of properties of a specified list instance. Requires the target list ID.

SP - List

LookupSPListItem

Returns properties of a specified SharePoint list item, presenting the values in a DynamicValue variable. Requires the target list item ID and the target list ID. Can also be configured with the fields to retrieve, using a collection of strings. The result will be a variable of DynamicValue type.

SP - List

LookupSPListItemId

Returns the ID property of the first SharePoint list item that matches the specified filtering criteria, based on field name and value. Requires the target list ID, property name, and property value. Returns the ID (Int32) of the retrieved item, if any.

SP - List

UndoCheckOutItem

Undoes the checkout of an item. Requires the target list ID and the target list item ID.

SP - List

UpdateListItem

Updates one or more properties of a specified SharePoint list item. Requires the target list ID, list item ID, and list of properties and values to update as a DynamicValue variable.

SP - List

WaitForFieldChange

Waits for a specified field of a specified SharePoint list item to change to a specified value. Requires the target list ID, SharePoint list item ID, and field name and value, to monitor for the change event. Returns a DynamicValue field.

SP - List

WaitForItemEvent

Waits for a specified event happening on a specified item on which the workflow is running. Requires the target list ID, SharePoint list item ID, and event to wait for. The available events are ItemAdded and ItemUpdated. Returns the ID (Int32) of the item related to the event.

SP - List

CompositeTask

Runs a task process, assigning multiple tasks to multiple people in parallel or series, waits for tasks to complete, and calculates aggregate outcome. Accepts arguments for configuring approvers, email notification behavior, task content type, available outcome values, and so on. Returns an aggregated outcome in a variable.

SP - Task

SingleTask

Runs a single task process, assigning the task to a single person or to a group and waiting for task completion. Accepts arguments for configuring the task assignee, email notification behavior, task content type, available outcome values, and so on. Returns an outcome value in a variable, as well as the ID of the created task item.

SP - Task

LookupSPGroup

Retrieves the properties of a target group. Requires the principal ID (Int32) of the group and returns the properties as a variable of type DynamicValue.

SP - User

LookupSPGroupMembers

Retrieves the properties of members of a target group. Requires the principal ID (Int32) of the group and returns the properties as a variable of type DynamicValue.

SP - User

LookupSPPrincipal

Returns properties of a target principal (that is, a user or a group). Requires the user name (String) of the target user or group and returns the properties as a variable of type DynamicValue. Optionally, can also add the principal to the current SPWeb instance, if it does not already exist in the current website.

SP - User

LookupSPPrincipalId

Returns the principal ID (Int32) of a user or a group, through its user name (String). Optionally, can also add the principal to the current SPWeb instance, if it does not already exist in the current website.

SP - User

LookupSPUser

Retrieves the properties of a target user. Requires the principal ID (Int32) of the user and returns the properties as a variable of type DynamicValue.

SP - User

AppOnlySequence

Is a container activity that executes all activities inside of its scope with the identity of the workflow, instead of using the identity of the workflow initiator user.

SP - Utilities

DelayUntil

Delays the execution of the workflow until a specified DateTime value, if that date and time has not already passed.

 

Email

Sends an email message to SharePoint users. Requires email subject and body. Can optionally accept To, CC, BCC, and additional headers. The fields To, CC, BCC, and Additional Headers are collections of strings.

SP - Utilities

LookupSPChoiceFieldIndex

Returns the index of a specified value in a SharePoint Choice field.

SP - Utilities

TranslateDocument

Creates a translated copy of a document, copying the result into a specified target library. Uses SharePoint Translation Services and requires a preconfigured Machine Translation Service application. Requires the source list ID, the source document list item ID, the destination list ID, and the language to translate the document to.

SP - Utilities

WaitForCustomEvent

Waits for a custom event to be sent into the workflow. Requires the name of the event as a String value. It optionally returns the event result as a String value.

SP - Utilities

WorkflowInterop

Starts a SharePoint 2010 (Microsoft Windows Workflow Foundation [WF] 3.5) workflow instance. Accepts input arguments for configuring the workflow definition, the target list item, the startup parameters, and so on. Returns the GUID of the started workflow instance, and optionally a variable of type DynamicValue with the values of the variables of the target workflow instance at completion. Can be configured to wait for the workflow completion, suspending the current workflow instance.

SP - Utilities

WriteToHistory

Writes a comment to the workflow history list. Requires the input message as a String type.

SP - Utilities

The Workflow Manager infrastructure provides some additional activities that are useful while designing SharePoint 2013 workflows. Although these activities are not only for SharePoint workflows, they are surely useful when developing them. Table 17-2 lists these activities.

Table 17-2. The activities available in Visual Studio 2012 workflows with Workflow Manager

Activity name

Description

Group

GetS2SSecurityToken

Retrieves a server-to-server (S2S) security token as a variable of type SecurityToken. Can also retrieve an app-only S2S security token in case it’s needed.

Messaging

HttpSend

Sends an HTTP request to a target web server. Can use any of the following verbs: GET, POST, PUT, DELETE, PATCH, HEAD, COMMENT, OPTIONS, TRACE, and CONNECT. Accepts arguments like the target URI, request content, request headers, response content, response headers, and response status code. Can also accept an argument of type SecurityToken if the connection will use an S2S secured communication.

Messaging

AddToDictionary<TKey, TValue>

Adds an item to a dictionary. Accepts a target dictionary, a key, and a value.

Collection

ClearDictionary<TKey, TValue>

Clears a target dictionary.

Collection

CountDictionary<TKey, TValue>

Count the number of items in a target dictionary.

Collection

DictionaryContains<TKey, TValue>

Checks if a target dictionary contains a specific value. Returns a Boolean value.

Collection

GetDictionaryValue<TKey, TValue>

Gets an item value from a dictionary, based on its key.

Collection

RemoveFromDictionary<TKey, TValue>

Removes an item from a dictionary, based on its key.

Collection

BuildDictionary<TKey, TValue>

Creates and initializes a new dictionary. Accepts the key and value pairs, and returns a new dictionary variable.

Collection

SplitKeyValuePair<TKey, TValue>

Splits key and value from a given key/value pair.

Collection

BuildDynamicValue

Builds a DynamicValue variable out of a set of paths and values. If the passed DynamicValue variable is null, then creates and initializes it. If not null, adds new properties to it.

DynamicValue

ContainsDynamicValueProperty

Returns true if a property is contained in a DynamicValue variable.

DynamicValue

CopyDynamicValue

Copies properties from one DynamicValue variable to another.

DynamicValue

CountDynamicValueItems

Returns the number of items in a DynamicValue variable.

DynamicValue

CreateDynamicValue

Creates one DynamicValue variable with a path that can be passed at run time.

DynamicValue

GetDynamicValueProperties

Get properties from a DynamicValue variable.

DynamicValue

GetODataProperties

Gets the value of multiple properties from an OData message provided as a DynamicValue variable.

DynamicValue

GetDynamicValueProperty<T>

Gets one property of a DynamicValue variable.

DynamicValue

IsEmptyDynamicValue

Returns true if a given input DynamicValue variable is empty.

DynamicValue

ParseDynamicValue

Parses JSON code into a DynamicValue variable.

DynamicValue

Now imagine that you want to create a simple workflow definition that targets a document library, retrieves the current item, checks out the document, and writes an item in the associated history list. Insert a CheckOutItem activity and configure it to check out the current item, configuring values of the ListId and ItemId properties with the values of the automatically provided values defined as (current list) and (current item).

More Info

The workflow designer in Visual Studio 2012 allows you to automatically choose the current target list ID and target item ID values by choosing the values (current list) and (current item), where available.

Then add a WriteToHistory activity and configure its Message property to an explicit string value of Document checked-out!. Figure 17-10 illustrates the result in the workflow designer.

A screen shot showing the workflow designer during the editing of a sample workflow in Visual Studio 2012. It displays the activities available in the toolbox on the left, the workflow design surface in the middle, and Solution Explorer on the right.

Figure 17-10. The sample workflow designed in Visual Studio 2012.

Notice that you have not defined any code. You simply configured the workflow definition using the designer and the properties of the defined activities with their underlying Microsoft C# or Visual Basic expressions. This is one of the key features of workflows in SharePoint 2013: they are markup based. You do not have to write any code, even if you define a workflow in Visual Studio 2012.

Note

If you previously defined workflows with SharePoint 2010 and WF 3.5, you are probably familiar with the CodeActivity activity. With SharePoint 2013 and WF 4.5, this activity has been removed.

Now you are ready to build, deploy, and test your workflow definition. Right-click the project in Solution Explorer and select the Deploy menu item. Now open the browser and navigate to the Documents library. Open the Workflow Settings page, which is available on the Library ribbon tab, and check the available workflows. You should see the workflow you just deployed, as illustrated in Figure 17-11.

A screen shot illustrating the Workflow Settings page of a document library. It displays all the available workflow associations, including the new workflow definition just defined.

Figure 17-11. The Workflow Settings page of a document library.

To execute an instance of the workflow, select any of the documents in the target library, click the Files ribbon tab, and click the Workflows ribbon button. You will be prompted with the Workflows page of the selected item. Click the workflow name to start a new instance. As soon as you start the workflow, the target document becomes checked out. Click the ECB menu and select the Workflows menu item to access the Workflows page (Figure 17-12).

A screen shot depicting the Workflows page of a single document in a library. It includes all the running workflow instances, if any, as well as the already completed workflow instances. From the page, you can access the details of a single workflow instance.

Figure 17-12. The Workflows page of a document item in a document library.

Click the Internal Status column, where you see a value of Completed, to access the Workflow Status page of that completed workflow instance. As shown in Figure 17-13, the workflow instance has an Internal State value of Completed, and the Workflow History list reports a single item with the description defined in the workflow definition in Visual Studio 2012.

The workflow instance you have just associated with the target library of orders does not provide a custom workflow status column. In fact, workflows created with Visual Studio 2012 by default do not provide implementation for such a column. Later in this chapter, in the “Workflow deployment” section, you will learn how to turn it on.

A screen shot illustrating the Workflow Status page of a workflow instance executed against a specific document. It includes general information about the workflow instance; the list of tasks, if any; and the items in the workflow history, if any.

Figure 17-13. The Workflow Status page of a workflow instance executed against a specific document.

To test and debug your workflow definition, you can place a breakpoint within the designer on any of the activities you defined. Suppose you want to break and debug starting from the GetCurrentListId activity instance. Press F5 to start debugging the project. Visual Studio 2012 will deploy the workflow project to SharePoint, and will start a console process that acts as a Workflow Manager instance dedicated to debugging.

More Info

The Workflow Manager instance dedicated to debugging corresponds to the process Microsoft.Workflow.TestServiceHost.exe, which by default is available in the folder C:Program Files (x86)Workflow Manager Tools1.0. This process emulates a Workflow Manager. Visual Studio 2012, while debugging a workflow for SharePoint 2013, registers this emulator in SharePoint 2013, in order to intercept requests and debug workflow instances.

Starting a workflow instance while debugging will raise within Visual Studio 2012 any breakpoint you declared in the workflow definition. Figure 17-14 shows the console output of the Workflow Manager emulator.

A screen shot showing the console window of the Workflow Manager emulator available in Visual Studio 2012 for debugging SharePoint 2013 workflows. The console highlights the URI of the endpoint where the emulator listens for requests, as well as the GUID of any workflow instances started or completed.

Figure 17-14. The console screen of the Workflow Manager emulator available for debugging SharePoint 2013 workflows within Visual Studio 2012.

Here is the output, in the console window, provided by the emulator after executing a sample workflow instance:

Listening at http://sp2013srv01.sharepoint.local:12292/
Runtime and gateway started, press <Enter> to exit.
Instance '866d65ba-4870-4ef7-8730-2d48eb8fa9d6' of workflow fb5b0c53-2f56-46a3-b3db-c07f0c13e591
Status: Started; Details: .
Instance '866d65ba-4870-4ef7-8730-2d48eb8fa9d6' of workflow fb5b0c53-2f56-46a3-b3db-c07f0c13e591
Status: Completed; Details: .

While debugging the workflow, expect to have a slow environment, because the overall debugging infrastructure is a little bit heavy to run and manage, and it is resource-consuming, too.

Workflow and SharePoint apps

The sample workflow you just defined requires a farm-level solution for deployment, so it is not suitable for publishing in Microsoft Office 365. If you instead define a workflow in a SharePoint app project, however, you can then publish it on-premises or on Office 365 via the cloud. Thus, the best practice is to create workflow definitions in apps, rather than in farm-level solutions.

To do so, create a new SharePoint 2013 app project—for instance, targeting an Office 365 tenant. Choose a SharePoint-hosted app, define a document library instance called Orders in the app website, and add a new item of type Workflow. Imagine that the library holds a set of orders that need approval by a manager, and name it OrdersWorkflow.

More Info

For further details about creating a SharePoint 2013 app, the available hosting models, and how to add a document library instance, see Chapter 8

The sample will be a list workflow, and the workflow creation wizard provided by Visual Studio 2012 is smart enough to suggest that you associate the workflow with any of the libraries defined in the current SharePoint app (see Figure 17-15).

A screen shot depicting the wizard provided by Visual Studio for creating a new workflow definition within a SharePoint app. The wizard includes fields for specifying the target library, the history list, and the tasks list.

Figure 17-15. The wizard for creating a workflow definition in a SharePoint app, using Visual Studio 2012.

If the Workflow History list and the Workflows Tasks list are not already available in the SharePoint app, you can define them explicitly, or you can simply ask the wizard to create them for you in the target app website.

While a real approval workflow definition should handle such input arguments as the target approver and the approval request message, the sample approval workflow will define explicit and fake values for these arguments. Later, you will use an initiation form. For now, create variables for holding the TargetApprover (String), the ApprovalRequestMessage (String), the ApprovalTaskId (Int32), and the ApprovalTaskOutcome (Int32) values.

Insert a SingleTask activity instance into the sequence defining the workflow, and configure its properties by clicking the Configure link provided in the designer. You will be prompted with a pop-up configuration screen (see Figure 17-16), where you will be able to configure all the main properties of the task. As you will see, a SingleTask activity has many required properties. Table 17-3 lists the values configured in the current sample.

A screen shot showing the SingleTask activity, together with its Task Options pop-up designer windows. The pop-up window provides UI elements to configure the task assignee, the task title, and the task due date, as well as task options, email options, and outcome options.

Figure 17-16. The Task Options designer provided by the SingleTask activity within Visual Studio 2012.

Table 17-3. The configuration of the main properties for the SingleTask activity

Property name

Value

Notes

AssignedTo

TargetApprover

An argument with a predefined value of i:0#.w|sharepoint\administrator or [email protected]. Later it will be taken from the workflow initiation form.

DueDate

DateTime.UtcNow.AddDays(5)

The number of days, which should be taken from the workflow initiation form.

Body

ApprovalRequestMessage

An argument with a predefined value of Please approve this order. Later it will be taken from the workflow initiation form.

ContentTypeId

Workflow Task (SharePoint 2013)

A ContentTypeId with a value of 0x0108003365C4474CAE8C42BCE396314E88E51F, corresponding to the out-of-the-box Workflow Task (SharePoint 2013) content type. You can also provide a custom content type ID for a custom task, as described later, in the “Custom workflow tasks” section.

OutcomeFieldName

Task Outcome

The value to select before selecting the DefaultTaskOutcome property value.

DefaultTaskOutcome

Rejected

A value dependent on the field selected in the OutcomeFieldName property.

Title

“Order Approval Task”

An explicit value. You should read it from a variable.

CompletedStatus

“Completed”

The explicit value of the localized string describing the completed status. You should read it from a variable.

WaitForTaskCompletion

True

A Boolean value that instructs the workflow process to wait for task completion.

OverdueReminderRepeat

Daily

An explicit value. You should read it from a variable.

Outcome

ApprovalTaskOutcome

An output variable of type Int32. If the activity is configured with the WaitForTaskCompletion property with a value of true, upon task completion this property will provide the index of the task outcome value, taken from the available values defined for the field declared in the OutcomeFieldName property.

TaskId

ApprovalTaskId

The item ID of the task item created in the task lists.

Notice that when you add a SingleTask activity or a CompositeTask activity to the workflow designer, the activity automatically adds variables to the current context for holding fundamental field values like task outcomes and others. You can use these automatically created variables, or you can replace them with custom variables of your own.

Now you need to determine if the task outcome is an approval of the order or a rejection. Insert an If activity, which is available in the Control Flow group of native activities. In the condition, enter the following expression:

ApprovalTaskOutcome == 0

The 0 value corresponds to the Approved outcome value, which is the first value defined in the underlying field type. In the left branch, which is the one labeled as Then, insert a WriteToHistory activity, providing a value of Approved for the Message property. In the right branch, which is the one labeled as Else, insert another WriteToHistory activity, providing a value of Rejected for the Message property. The sample workflow definition is now complete. Take a look at the final workflow outline in Figure 17-17.

A screen shot depicting the sample order-approval workflow. Solution Explorer is on the right side, and the workflow definition is in the middle. The workflow definition is made of a Sequence activity, with a SingleTask activity, an If activity, and two WriteToHistory activities—one for each branch of the If activity.

Figure 17-17. The outline of the sample order-approval workflow in the designer provided by Visual Studio 2012.

Now press F5 to deploy and debug the SharePoint app, or deploy it and then test it through the web browser as if you were an end user. If you debug the app by pressing F5, because the project contains a workflow definition, the Visual Studio 2012 debugger will start the Workflow Manager emulator, too. If you simply deploy and test the app from the browser, you will use the standard Workflow Manager. You will not, however, be able to raise breakpoints and step into the workflow definition unless you do not attach the Internet Information Services (IIS) worker process with the debugger. Moreover, consider that workflow debugging is allowed only in on-premises environments and cannot be done while targeting Office 365. If you try to debug a workflow project targeting Office 365, Visual Studio 2012 will raise a debug error, providing you the pop-up message shown in Figure 17-18.

A screen shot illustrating the error message prompted by Visual Studio 2012 during debugging of a workflow targeting Office 365. The message states, “Workflow debugging prerequisites failed to complete. Would you like to disable workflow debugging in order to debug other parts of this project? Workflows will still be installed but will not have debugging support.”

Figure 17-18. The pop-up error message raised by Visual Studio 2012 during the debugging of a workflow targeting Office 365.

More Info

You can also enable or disable workflow debugging by changing the Enable Workflow Debugging option on the SharePoint tab in the SharePoint app project properties.

Figure 17-19 shows the Workflow Status page of the sample workflow definition while running on a target document.

A screen shot illustrating the Workflow Status page of the sample order-approval workflow defined in Visual Studio 2012. The display includes the workflow’s general information, the list of tasks with an active task, and the Workflow History list.

Figure 17-19. The Workflow Status page of a sample order-approval workflow defined in Visual Studio 2012.

Figure 17-20 shows the task form for completing the approval task. It is an ASP.NET form, which is almost the same as the one available while developing workflows in SharePoint Designer 2013. Moreover, consider that starting with SharePoint 2013, the workflow task forms cannot be created using Microsoft InfoPath Forms Services; the only option you have is to use ASP.NET forms.

A screen shot depicting the ASP.NET task form for approving or rejecting an order. The form is a classic SharePoint item form, with a couple of additional buttons in the bottom area. The two buttons enable you to approve or reject the current task.

Figure 17-20. The ASP.NET task form for approving an order for the approval workflow for the sample orders.

Lastly, while a workflow created in a farm-level solution by default does not present the workflow status column, a workflow defined in a SharePoint app does present that column, as do workflows created with SharePoint Designer 2013.

Workflow forms

In this section, you will learn how to create custom workflow forms. To create a workflow association or initiation form, you can simply use Visual Studio 2012. Right-click the workflow element in Solution Explorer, and then choose to add a new item. From the resulting list of available items, choose a Workflow Initiation Form template type (see Figure 17-21). The suggested file name will be for an ASPX page file.

A screen shot illustrating the Add New Item window for a workflow element in Visual Studio 2012. The list of available item templates includes Workflow Initiation Form, Workflow Association Form, and Workflow Custom Activity, as well as many other standard SharePoint elements.

Figure 17-21. The Add New Item window for a workflow element in Visual Studio 2012.

After you add the Workflow Initiation Form item, Visual Studio prompts you with the source code of the ASPX page file, which will be placed in the Pages folder of the current SharePoint app project. The page is made of a Content control targeting the PlaceHolderMain region of the default master page of SharePoint. The Content control contains ASP.NET, HTML, and JavaScript code completely commented (and left there for the sake of providing an example of some of the most common ways of rendering input fields for initiation arguments of type String, Integer, and DateTime). The ASPX file provides a couple of sample buttons to start the workflow instance or cancel the initiation. Lastly, at the end of the file is a small piece of JavaScript code that, using the Client-Side Object Model (CSOM) and the Workflow Services Manager client library, starts a new workflow instance providing the arguments configured by the user through the initiation form.

More Info

The Workflow Services Manager client library is available in the JavaScript file sp.workflowservices.js, which is referenced in the PlaceHolderAdditionalPageHead region of the initiation form page.

An excerpt of the source code of a sample workflow initiation form shows an excerpt of the source code of the initiation form.

The JavaScript code that starts the workflow instance is highlighted in bold. Note that you can define the initiation form any way you want, from a markup and design viewpoint. The only important thing is to start the workflow instance using the JavaScript code. Of course, having a code excerpt for handling all the most useful data types and for starting a workflow instance is a great aid.

To start the workflow providing input arguments, the JavaScript code retrieves the current SP.ClientContext instance. Through this, it gets a reference to a new instance of the SP.WorkflowServices.WorkflowServicesManager class, which will be explained in detail in Chapter 18. For now, it will suffice to know that the WorkflowServicesManager instance retrieves a reference to the types useful for resolving the current workflow definition. Using the TemplateID query string parameter, which will be provided to the initiation form by SharePoint, the JavaScript code retrieves the workflow definition associated with the current initiation form, and starts the workflow instance using either the startWorkflow method or the startWorkflowOnListItem method of the WorkflowInstanceService class, depending on the target of the workflow.

Important

The WorkflowInstanceService type, which is used to start a workflow instance in the JSOM, provides two methods for starting a new workflow instance: startWorkflow and startWorkflowOnListItem. Which one you should use depends on the type of workflow definition you are starting. The startWorkflow method starts a site workflow and accepts the workflow subscription and the arguments. The startWorkflowOnListItem method starts a list workflow and accepts the workflow subscription, the target item ID (Int32), and the arguments.

Now go back to the OrdersWorkflow definition you designed in the previous section. To retrieve values provided through the initiation form, you need to define workflow arguments corresponding to the fields configured in the form. In the current OrdersWorkflow sample, delete the variables ApprovalRequestMessage and TargetApprover and replace them with a couple of arguments with the same name and type (String). You need to adapt the initiation form accordingly. Leave the String field in the page, deleting the Integer and DateTime sample code excerpts. Then change the JavaScript code to provide the right startup arguments. As you can see from reading the code highlighted in bold in An excerpt of the source code of the OrdersWorkflow initiation form, a client-side PeoplePicker control has been inserted, which is new in SharePoint 2013. This new control allows selecting a user, a group, or a distribution list from the client code using JavaScript. This control will be used to retrieve the value for the TargetApprover argument.

More Info

For further details about the client-side PeoplePicker control, you can read the article “How to: Use the client-side PeoplePicker control in apps for SharePoint,” available on MSDN at the following URL: http://msdn.microsoft.com/en-us/library/jj713593.aspx. You can also consider the code sample available here: http://code.msdn.microsoft.com/SharePoint-2013-Add-the-900e0742.

Because the OrdersWorkflow definition targets a list workflow, the JavaScript code will use the startWorkflowOnListItem method, providing as arguments the workflow subscription ID corresponding to the current workflow definition, the ID of the current item taken from the query string, and a dictionary of arguments that will have to match the arguments defined in the workflow designer of Visual Studio 2012. The sample workflow initiation form will also resolve the selected target approver user key using some custom JavaScript code, which is a modified version of the code provided by MSDN for using the client-side PeoplePicker control. An excerpt of the JavaScript code to retrieve the user key provided by the client-side PeoplePicker control shows the JavaScript code for resolving the target approver.

To test and check the arguments, you can add a couple of WriteToHistory activities for writing the two arguments to the Workflow History list.

However, to effectively use the initiation form, you will need to configure the workflow project item in the Visual Studio 2012 project. In Solution Explorer, click the OrdersWorkflow item to edit its properties using the standard property grid of Visual Studio 2012. There you will find a long list of properties, including one named InitiationUrl. Through the InitiationUrl property, you can define the ASPX page to use as the initiation form for your workflow. When you add an initiation form through Visual Studio 2012, it automatically adds the proper value to the workflow configuration.

Deploy the SharePoint app and start a workflow instance; you will be prompted with an initiation form like the one shown in Figure 17-22.

A screen shot showing the workflow initiation form for the sample OrdersWorkflow definition. It includes fields for configuring both the ApprovalRequestMessage and TargetApprover arguments.

Figure 17-22. The workflow initiation form for the sample OrdersWorkflow definition in Visual Studio 2012.

The form displays a field for providing the content of the ApprovalRequestMessage argument, and the client-side PeoplePicker control for providing the value of the TargetApprover argument.

The workflow association form will be almost the same as the workflow initiation form. The only difference will be the JavaScript code behind the form. By using the association form, you will need to define the association, which in SharePoint 2013 is represented by a WorkflowSubscription type instance and its configuration properties. However, consider that in SharePoint 2013, many of the workflows you will develop in Visual Studio 2012 will be defined within SharePoint apps. Thus, the association of the workflow with its target list, library, or site will happen during the provisioning of the app, because end users usually do not configure lists, libraries, and the app website manually. Meanwhile, if you are developing a farm-level workflow, you may also need to create a custom workflow association form. In Chapter 18, you will learn how to publish a WorkflowSubscription instance, using the Workflow Services Manager client library, and write an association form page for a workflow defined in a farm-level solution.

Custom workflow tasks

You can further customize your workflows by creating custom tasks and defining custom task fields and custom task forms. To create a custom task, you first define a custom content type, inheriting from the basic Workflow Task (SharePoint 2013) content type.

More Info

For details about how to create a custom content type, please refer to Chapter 3 as well as Chapter 8.

Within the custom content type definition, declare a site column for holding a custom task outcome, which will be the customization defined in the custom task. The XML code declaring the custom OrderApprovalTask content type shows the source XML code declaring the new task content type.

Notice that the custom task inherits from the Workflow Task (SharePoint 2013) content type (0x0108003365C4474CAE8C42BCE396314E88E51F), but it does not inherit the UI from the parent content type (attribute inherits with a value of FALSE). On the contrary, the ContentType element is configured to use a custom set of forms, which are configured as relative URLs mapping to custom ASPX pages defined in the Pages folder of the current SharePoint app project. Also notice that the custom site column for holding the task outcome is of type OutcomeChoice, which is a new SharePoint 2013 type defined for holding the outcome of a workflow task.

The custom ASPX page implementing the task form, which is illustrated in The ASPX code of the custom workflow task form, defines some custom UI elements and provides three buttons to approve, reject, or submit the order for review. Based on the JSOM, the code behind the page simply updates the current task item, which was retrieved using the List and ID query string arguments, and sets the OrderApprovalOutcome field according to the user’s choice.

To use the new task content type, you could add to the app website a new list of tasks of this type. A better practice, however, is to use the wizard that adds a new workflow definition. By default, this wizard creates a tasks list for you; you should edit the list definition of that tasks list instead of creating a new one from scratch.

Open the Elements.xml file related to the tasks list and add a ContentTypeBinding element using a code excerpt like the one highlighted in bold in The code for provisioning the Workflow Tasks list, including a custom task content type.

The ContentTypeBinding element binds the custom content type to the tasks list definition available out of the box in SharePoint, and referenced through its TemplateType ID, which has a value of 171. In the current example, the content type ID of the custom task content type is the ContentTypeBinding element (highlighted in bold). Now, moving to the workflow definition, you can insert a SingleTask activity or a CompositeTask activity, and you can configure the task content type to match the new custom content type (see Figure 17-23).

A screen shot illustrating the property editors of a SingleTask activity configured for using a custom task content type. On the left side is the property grid, and on the right side is the Task Options dialog window. Regardless of the UI you will use to configure the custom task, there is a field for configuring the content type with a value of OrderApprovalTask; the default task outcome property, configured with a suitable value; and the outcome field name, configured with a value of OrderApprovalOutcome.

Figure 17-23. The property editors of a SingleTask activity configured for using a custom task content type.

You can configure the custom task using either the standard property grid of Visual Studio 2012 or the Task Options pop-up window available in the workflow designer.

Discussing the whole approval workflow is out of scope for this context. In short, you define the workflow process using whatever activities you like, and then deploy and test it. In Figure 17-24, you can see how the custom task form behaves in the web browser when the assignee edits it.

A screen shot illustrating the custom workflow task form in action. It includes three buttons—for approving an order item, rejecting it, and submitting it for review.

Figure 17-24. The custom workflow task form rendered in the web browser.

Workflow deployment

Now that you can develop a workflow definition, you’re ready to delve into the workings of the workflow deployment process. This topic varies depending on the type of project you are defining. For example, a farm-level solution behaves differently from a SharePoint app project.

Farm-level workflow

When you deploy a project that includes a workflow definition in a farm-level solution, you can use the standard Module feature element. The feature element file for deploying a sample workflow definition shows the feature element deploying the sample approval workflow defined earlier in the chapter, in the section “Visual Studio 2012 for creating workflows.”

The most interesting parts of the file are highlighted in bold. For example, the Module feature element provisions a pair of files with two content types:

  • WorkflowServiceDefinition. Represents a workflow definition, together with its configuration properties—for example, the target (list or site), and the InitiationUrl and AssociationUrl properties, if any.

  • WorkflowServiceSubscription. Declares an association between a WorkflowServiceDefinition and a target. This file defines the name, the activation type, the tasks list, the history list, and so on.

The workflow by itself is deployed in a folder relative to the wfsvc library. The folder will have a unique name. The workflow feature provisions the wfsvc library, which effectively holds the workflow definition files, which include the XAML file, the association file, any forms, and so on.

The file with content type WorkflowServiceDefinition supports many configurable properties. The most interesting are

  • WSDisplayName. Represents the display name of the workflow definition. It is visible to the end users when configuring new workflow associations.

  • WSDescription. Represents the description of the workflow definition. It is visible to the end users when configuring new workflow associations.

  • InitiationUrl. Represents the relative URL of the workflow initiation form, if any.

  • AssociationUrl. Represents the relative URL of the workflow association form, if any.

  • RestrictToType. Limits the available event source type for the workflow subscriptions based on the current workflow definition. The available values are List, Site, and empty or null, which behave the same.

  • RestrictToScope. Is a GUID value or an expression that will be processed by Visual Studio 2012 during packaging of the WSP file, which further restricts the scope of the current workflow definition. For example, if the RestrictToType property has a value of List, then this property can assume the value of the GUID of a specific list.

The default workflow-provisioning template available in Visual Studio 2012 does not use any initiation or association form. However, if you add a workflow initiation form or a workflow association form, Visual Studio 2012 will add the corresponding Property and File elements to the feature element file. By default, when you add a workflow initiation or association form while working in farm-level solutions, Visual Studio 2012 places the forms’ files within the same folder that hosts the workflow definition.

The file with content type WorkflowServiceSubscription supports many other configurable properties. The most interesting are

  • WSDisplayName. Represents the display name of the workflow subscription. It is visible to the end users while starting a new workflow instance.

  • WSEventType. Defines the list of event types for which the workflow subscription is listening.

  • WSEnabled. Defines whether the current workflow subscription is enabled or not.

  • WSEventSourceGUID. Defines the unique ID (GUID) of the event source corresponding to the WSEventType value. Usually it is the ID of the target list or library if the workflow is a list workflow.

  • ListId. Defines the ID of the target list if the workflow is a list workflow.

  • HistoryListId. Defines the ID of the history list, if any.

  • TaskListId. Defines the ID of the tasks list, if any.

  • StatusColumnCreated. Declares whether the workflow subscription should have a workflow status column or not.

The supported values for the WSEventType property are

  • WorkflowStart. Allows the workflow to be manually started by an authenticated user with Edit Item permissions

  • ItemAdded. Starts the workflow when a new item is created

  • ItemUpdated. Starts the workflow when an item is updated

Workflow features use a dedicated feature receiver, declared in the SPWorkflowPackageFeatureReceiver class of the Microsoft.SharePoint.WorkflowServices namespace. This feature receiver accepts only features with a web scope, and if the workflow is properly configured, this feature receiver registers the workflow status column to the target list or library.

To accomplish the status column–registration task, you need to configure the StatusColumnCreated property of the File element with content type WorkflowServiceSubcription. Here is a code excerpt of the property to configure:

<Property Name="StatusColumnCreated" Value="1" />

A value of 1 instructs the feature receiver to create a status column with a name equal to the workflow association name. Any other value will not create the workflow status column.

By configuring all the properties illustrated in this section, you can determine the provisioning of your workflow definitions. Usually, the out-of-the-box provisioning files will suffice, but if necessary, you can edit the feature element file to adhere to your requirements.

SharePoint app workflow

When you deploy a workflow definition through a SharePoint app project, Visual Studio 2012 hides all the inner workings from you. The deployment is managed for you, and you simply have to configure a set of properties that determine the behavior of the deployment process. To edit these properties, click the workflow item in Solution Explorer and work through the property grid of Visual Studio 2012 (see Figure 17-25).

A screen shot depicting the property grid of a workflow definition. It includes properties to configure the description, display name, history list, tasks list, initiation and association forms URLs, startup behavior, target list, and others. In the screen shot, the Initiation Url property is highlighted.

Figure 17-25. The property grid of a workflow defined in a SharePoint app in Visual Studio 2012.

As you can see, there are properties for managing all the most common configuration parameters, including description, display name, history list, tasks list, initiation and association form URLs, startup behavior, and target list. For instance, if you want to configure the workflow to start when a target item is added, you can simply change the value of the property Start On Item Added to true. Moreover, if you want to configure the URL of the initiation or association form, you need to choose or provide a value for the Initiation Url and Association Url properties.

Behind the scenes, the editor will configure some XML elements in a file named SharePointProjectItem.spdata, which is placed in the same folder as the XAML file with the source code of the workflow definition.

Flowcharts and state machines

So far, using Visual Studio 2012, you have designed only sequential workflows. However, you can also use flowcharts and state machines in SharePoint 2013 workflows. From an operational viewpoint, designing a flowchart or a state machine is not that different from creating a sequential workflow. You simply need to delete the Sequence activity, which is provided by default by Visual Studio 2012 within the workflow item template for SharePoint, and replace it with a Flowchart or StateMachine activity. For example, Figure 17-26 illustrates a sample flowchart-based approval workflow for SharePoint 2013 in the workflow designer.

A screen shot depicting a flowchart workflow definition in the workflow designer of Visual Studio 2012. The design area contains a typical representation of a flowchart, with a starting point, an action, a decision block, and three actions corresponding to the possible results of the decision block.

Figure 17-26. The workflow design surface of Visual Studio 2012 for a flowchart workflow.

More interesting than how to design the sequences, flowcharts, or state machines is when to use which kind of model. The answer depends on the functional requirements of your project:

  • Sequential workflow. A good option whenever you need to define a flow with clear starting and ending points, with a defined path to move from the beginning to the end, and without the need to step back in the flow process. For example, a sequential workflow is the right choice for defining maintenance processes, and is often used in site collection–level workflows.

  • Flowchart workflow. The right solution for implementing decision-based processes. Flowcharts are based on the idea of performing an action, evaluating the action result or a condition, making a decision, performing another action, and so on. With a flowchart, you can come across the same portions of a flow process multiple times. It is a suitable option for defining approval processes with moderate interaction with end users, loops, and so on. Not by chance, SharePoint Designer 2013 creates workflows as flowcharts when you use its workflow designer.

  • State machine workflow. The best choice for modeling a human-interactive process, like a document approval process. The states of the state machine correspond to the phases of the process. The outcome of every approval phase corresponds to a transition rule, which defines the target state to go to. When the process is completed, the state machine can make a transition to the final state. Even if every state machine can be defined using a flowchart, there are many situations, such as with approval processes, where a state machine is simpler to design and better self-documented in its design schema.

Summary

In this chapter, you learned how to create advanced workflows using SharePoint Designer 2013, consuming REST services using the Call HTTP Web Service action and the Dictionary data type. Then you moved on to designing workflows using Visual Studio 2012. You saw how to implement custom workflows targeting an on-premises farm, as well as how to create SharePoint apps that internally use custom workflows. You learned how to create custom workflow forms, custom tasks, and custom task forms. Then you saw how the deployment process of a workflow works. The chapter ended by comparing the various models of workflow definitions available.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset