Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#

Building and Testing a WCF Web Service Using Workflow Foundation 4.0

4.81/5 (24 votes)
22 Jul 2010CPOL13 min read 113.4K   2.2K  
Guide to build and test a simple Web Service in Workflow Foundation 4.0.

Table of Contents

Introduction

The goal of this article is to help developers get familiar with Workflow Foundation 4.0.

Workflow Foundation 4.0

It provides a programming model, in-process workflow engine, and a re-hostable designer to implement long-running processes as workflows within .NET applications. MSDN.

Building a WCF Service Using WF4.0

This article will provide a step-by-step guide to build and test a simple calculator Web Service in WF 4.0. I will be mostly using built-in WF activities to build the workflow. In addition, I will build a simple custom code activity to go over the custom activities.

The task of the service will be to take three parameters, two for operands and one for operation name, and return the result back to the client after applying the operation. The diagram below explains the complete flow that we are going to implement during this exercise, and our workflow will look like this flow chart at the end.

Visio-Workflow.png

Building workflow applications will be similar to building this flow chart. Each box in the above diagram will be called activity, and all the activities will be contained in a larger activity called Main Activity. Most of the activities needed to build this application will be provided by Visual Studio 2010, and we will add a new custom activity to log the data into a file to track the application.

Let's Get Started

Start New Project

  1. Launch Visual Studio 2010
  2. Select Project->New
  3. Select "WorkFlow" under "Installed Templates->Visual C#"
  4. Select "WCF Workflow Service Application"
  5. Change the name of the project to "CalculatorWFService"
  6. Click OK to close this window

Image1.png

This will create a project using a Workflow Service Template, with three built-in activities: Sequense, ReceiveRequest, and SendResponse (see the designer window in the figure below).

Image2.png

Sequence Activity

The SequenceActivity is a CompositeActivity, meaning the SequenceActivity can contain other activities. The SequenceActivity class coordinates the running of a set of child activities in an ordered manner, one at a time. The SequenceActivity is completed when the final child activity is finished.

Receive Activity

Receive Activity will wait until a client connects to the service and then runs its contained child activities. MSDN.

Send Activity

Client activity that models the synchronous invocation of a service operation.

Rename Service Operation Name and Contract Name

  1. Click on the sequence service to Main Sequence (to match the workflow in Fig. 1). This renaming will not have any effect on the application, but it will improve the readability of the workflow.
  2. Rename the Service1.xamlx file to CalculatorService.xamlx by right clicking on the file.
  3. By default, the workflow service template configures the service with the "GetData" web operation name (think of it as a web method). To rename this method, click on the "ReceiveRequest" activity and change the "Operation Name" property to "Calculate". Also, change the service contract property to "ICalculate".

Add Top Level Variables

Select the activity called "Main Sequence" and click on the "Variables" button at the bottom of the designer window.

Image3.png

This action will open up a Variables window (highlighted below).

Image4.png

Remove the "data" variable by selecting the complete row. As soon as the variable "data" is deleted, the designer will show an error icon on the activities which no longer have the "data" variable that they were using. This is a very helpful feature for debugging and tracking design time issues.

Image5.png

For now, let's just ignore these error icons and keep moving on. They will disappear after we are done with the activity configurations. Add variables to hold the three input parameters by clicking on the "Create Variable" text in the variable window. Create two parameters of type int32 (use the drop down control in the "variable type" column to select the variable type) and name them "Operand1", "Operand2". Create a third variable of type "string" and name it "OperationName". Also, let's add a fourth variable called "Result" of type string to hold the result (see the screenshot below) and send it back to the caller application.

Image6.png

These variables are just like adding class level variables which will be accessible to all the class methods. In this case, they will be available to all the activities within the "Main Sequence" activity.

Receive Activity Configuration

Now we have to configure the Receive Activity to accept the following three parameters. To do this, you will have to select the Receive Activity and change its "Content" property by clicking the dotdot.png button. This will open up the "Content Definition" window. Click on the parameter radio button to define the parameters. The Message data option can be used to receive custom class objects.

Image8.png

Define three parameters (as shown in the figure above) by clicking on the "Add new parameters" text. "parameter1" and "parameter2" will hold two numbers, and "operationName" will hold the name of the operation to be performed on these numbers.

Parameter to Workflow Variable Mapping

After adding parameters, we have to assign workflow level variables to the parameters so that all the input data will be available for all the workflow activities. To do this, just select the "Enter a VB expression" text in the cell next to the parameter name and type in the variable that you want to assign to the parameter. In this exercise, I will assign parameter1 to operand1, parameter2 to operand2, and operationName to the OperationName workflow variable.

Image9.png

Click OK to close the window.

Send Activity Configuration

To configure the Send Activity, select the "SendResponse" activity in the designer. Change its "Content" property to configure what to send back to the caller. Select the dotdot.png button next to 'Contents' in the property box. This will open up a new "Content Definition" window same as what we have seen before during the Receive Activity configuration. We do not have to configure parameters here. Message configuration will do just fine. Just remove "data.ToString()" with the "Result" variable that we have declared in the beginning. One more great feature of the designer is that it provides intellisense help throughout the process, and that makes it easier to select and find variables available (see screenshot below).

Image11.png

Click OK to close the window and get back to the designer.

Now we are done with the Web Service input and output configurations. The next step is to perform some operation based on the "operationName" parameter. For that, we are going to use a flow chart activity. Before we start to build a flow chart, let's build a custom code activity to log some trace information in a file and also add some text to the final result. We will use this activity in the flow chart.

Steps to Build a Custom Code Activity

  1. Right click on the CalculateWFService project and select Add New Item.
  2. Then, in the Installed Templates section, select "workflow".
  3. Select "Code Activity".
  4. Click "Add" to add this activity to the project (we will leave the default name "codeactivity1.cs" as is).
  5. Image12.png

  6. Every code activity can have input and output arguments just like any C# method having input and output parameters. I find it easier to think of it as a C# class method and the way it deals with the input and output parameters. The only exception is that in code activity, they have to be declared as InArguments and OutArguments, and have to be accessed via the current context. In this code activity, we are going to use the default text InArgument, and will add an OutArgument "result". Just type the following in the top section of the class:
  7. C#
    public OutArgument<string> result { get; set; }
  8. Add the following simple execution code in the Execute method of the code activity class:
  9. C#
    File.AppendAllText(@"C:\WorkflowLog.txt", "Result is:" + text);
    context.SetValue(result, "Result is:" + text);

    All this code is doing is writing the input of this code activity in a file and returning the input of the activity after appending some text in it. Also, you will have to add the following in the file header:

    C#
    using System.IO;

    In code activities, all the activity execution logic should be written in the Execute method. Please check the following link for more information on code activities and the Execute method: http://msdn.microsoft.com/en-us/library/ee264176.aspx.

  10. Build the project at this point to check for any errors and to add this new code activity in the "Toolbox".
  11. Image13.png

  12. Select "CalculatorService.xamlx" to go back to the designer.

Flowchart

There are other options to get the result, and this simple task can be accomplished by using a custom code activity or via a simple expression in the Send Activity's configuration. But my goal is to give an overview of as much workflow features as possible in this exercise, and this is why I am going to use a flow chart.

What is Flowchart Activity?

A Flowchart Activity is an activity that contains a collection of activities to be executed. Flowcharts also contain flow control elements such as FlowDecision and FlowSwitch that direct execution between the contained activities based on the values of variables.

Types of Flow Nodes

Different types of elements are used depending on the type of flow control required when the element executes. Types of flowchart elements include:

FlowStep

Models one step of execution in the flowchart.

FlowDecision

Branches execution based on a Boolean condition, similar to If.

FlowSwitch

Branches execution based on an exclusive switch, similar to C# switch. Each link has an Action property that defines a ActivityAction that can be used to execute child activities, and one or more Next properties that define which element or elements to execute when the current element finishes execution. You can fine out more about flowcharts here.

OK, enough about flowcharts; let's get started on building one to calculate the result.

Step 1: Expand the "Flowchart" section in the VS Toolbox, and drag the flowchart activity and drop it between the "ReceiveRequest" and SendResponse" activities (see the screenshot below).

Image14.png

Step 2: Double click on the text in the Flowchart activity to start drawing a flowchart. This will take you to the flowchart designer window. Please notice another great feature of the designer: breadcrumb navigation on the top of the designer which can be used to go back to the top level activities.

Step 3: Drag the "FlowSwitch<t>" activity from the toolbox and drop it under the Start activity. Select "String" on the "Select types" window, which will pop up as soon as the activity is dropped on the designer.

Image16.png

Switch Activity Configuration

  1. Select "Switch" in the designer window.
  2. Click on the button next to "Expression" in the property window.
  3. Type in "OperationName" in the expression editor (Intellisense will help you select the variable), and click OK to close the window.
  4. Now the switch is configured to evaluate the "OperationName" variable and to decide the path that it will have to take based on its value. So, let's define different paths for different values. In this exercise, I am going to only perform three calculations: addition, subtraction, and multiplication, and if operationName is not "add", "subtract", or "multiply", then I will return a "not implemented" message (take a look at the flow chart in the beginning of the article). Select "CodeActivity1" in the toolbox, and drop it four times in the flowchart designer window.
  5. Draw lines from the "Start" node to the "Switch" node, and then draw four lines from the "Switch" node to each of "CodeActivity1". To draw a line, just hover the mouse pointer over an activity and drag a line to the next activity.
  6. Select each line except the "default" line, and change "Case" in the property window to "add", "subtract", and "multiply", as shown in the figure below:
  7. Image17.png

    If you remember, "Text" is the input argument for the code activity, and "result" is the output argument. In the following few steps, we are going to set these input and output arguments for all the code activities that we dropped in the designer.

  8. Select the "CodeActivity1" which is linked to the "add" case, and type the "(Operand1 + Operand2).toString()" expression in the "Text" property. Type "Result" in the "result" property expression.
  9. Select the "CodeActivity1" which is linked to the "subtract" case, and type the "(Operand1 - Operand2).toString()" expression in the "Text" property. Type "Result" in the "result" property expression.
  10. Select the "CodeActivity1" which is linked to the "multiply" case, and type the "(Operand1 * Operand2).toString()" expression in the "Text" property. Type "Result" in the "result" property expression.
  11. Select the "CodeActivity1" which is linked to the "default" case, and type the "Not implemented" expression in the "Text" property. Type "Result" in the "result" property expression.
  12. Image18.png

The flowchart activity will check the input variable "OperationName" and will take the appropriate execution path. At the end of each path, we are setting the workflow level variable called "Result" to some value via "codeActivity1". After the flow chart, the workflow will execute the send activity which will result in the "Result" value sent back to the caller.

So this is it folks, our workflow service is ready.

WCF Web Service Test (Using WCFTestClient)

Now, let's test this using WCFTESTClient.exe. This exe can be found under the "C:\Program Files \Microsoft Visual Studio 10.0\Common7\IDE\WcfTestClient.exe" path. This tool can be used to test any WCF Web Service. Just follow the steps below to test our calculator service:

  1. Right click on the project and select Properties.
  2. Click on the "WEB" tab on the left of the properties page.
  3. Click on the "Start external program" radio button.
  4. Type the WCFTestClient.exe path in the textbox (C:\Program Files \Microsoft Visual Studio 10.0\Common7\IDE\WcfTestClient.exe).
  5. Save the application.
  6. Let's get the Web Service reference path by right clicking on the ".xamlx" file in Visual Studio's Solution Explorer window and selecting the "Browse" option for the menu. We will need this for the test utility.
  7. Image19.png

  8. Copy the Web Service link from the browser.
  9. Image20.png

  10. Press F5 to run the application.
  11. This will launch the WCFTestClient application; see the screenshot below:
  12. Image21.png

  13. Right click on the "My Service Project" to add the Web Service reference and paste the service path that we copied in Step 7. This will add the Web Service reference in the WCF test client application.
  14. Click on Calculate in the left window, and then expand it in the right side window to see all the input parameters. Set the input parameter values and click "Invoke" to invoke the Web Service method. The bottom "Response" window will display the result. Take a look at the screenshot below:
  15. Image22.png

Conclusion

Hope this exercise gave you some insight into Windows Workflow Foundation. In my next article, I will try to deploy this in IIS, and will configure it for monitoring using AppFabric. Also, I will try to go over some of the basic and most important workflow features like persistence, workflow execution, and monitoring using AppFabric.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)