Windows Workflow Foundation and Web Services

The ultimate goal of Windows Workflow is to simplify development of web-service-based business processes in .NET.


March 14, 2007
URL:http://www.drdobbs.com/windows/windows-workflow-foundation-and-web-serv/198000882

Brian is a Microsoft Certified Professional and Microsoft Certified Application Developer for .NET. Brian is also the author of Foundations of WF: An Introduction to Windows Workflow Foundation (Apress, 2007) on which this article is based.


Windows Workflow Foundation (WF) is the programming model and tools for building "workflow-enabled" (a set of related activities representing specific business logic) Windows applications. The ultimate goal of WF is to simplify development of business processes in .NET. One of the activities that Windows Workflow provides is an activity for working with web services, along with several activities that let your workflow become a web service. In this article, I introduce the InvokeWebService activity, which lets you work with existing web services. I also introduce three other activities—WebServiceInput, WebServiceOutput, and WebServiceFault—that let you create your workflow as a web service.

InvokeWebService Activity

Windows Workflow Foundation supports three workflows: Sequential, State Machine, and Data-Driven. You can use the InvokeWebService activity in both the Sequential and State Machine workflows. It's similar to using a web service in any other .NET application. First, you must reference the web service, then you can access it. To illustrate, I present a simple web service that returns a value of True. Although impractical in the real world, it gives a good example of how the interaction works.

The first step in this example is to create a simple web service. The completed web service, SimpleWebService, is available electronically; see "Resource Center," page 5. However, if you wish to build the web service, here are the steps to do it. (If you aren't familiar with web services, you can find an introduction to web services in Chapter 10 of my book Beginning Object-Oriented ASP.NET 2.0 with VB.NET; Apress, 2005.)

Create a new web site, choose ASP.NET Web Service, and call the service SimpleWebService. When the web service is created, open the Service.vb file if it isn't already open. Replace the HelloWorld default web method with the following:

Public Function IsUser(ByVal UserName As
                     String) As Boolean
   If UserName = "Brian" Then
     Return True
   Else
     Return False
   End    If
End Function

Build the web service, then close the project. To test the web service, enter:

http://
  localhost/SimpleWebService/Service.asmx 

in your web browser. The Service web service default page appears, listing the web methods (IsUser). Click the IsUser link, enter Brian as the UserName parameter, and click Invoke. An XML document appears in a new browser window; it says True. Close the XML document window, enter Me as the UserName parameter, and click Invoke. This time the XML document contains False, showing that the web service is working correctly.

Create a new VB Sequential Workflow Console Application called "VBWebServiceSequentialConsole." Drag an InvokeWebService activity onto the Workflow Designer. As soon as the activity is added to the workflow, the Add Web Reference window appears. Click the Web Services on the Local Machine link. A list of the web services on the local machine is listed here. Find the link with the URL listed as:

http://localhost/SimpleWebService/Service.asmx. 

The Services column lists Service. Click the URL. The Service default page appears as it did in the browser previously. Change the Web Reference Name to SimpleWebService and click the Add Reference button. This is the same as adding a web reference to a VB or C# application.

After the Add Web Reference window closes, click the InvokeWebService activity and view the properties. Change the name to InvokeSimpleWebService. Click the MethodName property and choose IsUser from the drop-down. Each InvokeWebService activity lets you interact with one web method exposed by the web service. Once you choose IsUser, the (ReturnValue) and UserName properties appear under Parameters, as in Figure 1. These two properties let you provide values or variable names that contain the values to send to the web method when it's called.

[Click image to view at full size]

Figure 1: InvokeSimpleWebService properties.

View the code for the workflow to add the necessary variables. Add the following code within the workflow class declaration:


Public LoginName As String = "Brian"
Public ValueReturned As Boolean = False

Return to the Workflow Designer, click the InvokeSimpleWebService activity, and view the properties. Click the ellipse next to the UserName property. This opens the Bind to Property window. Choose LoginName from the tree under Workflow1, as in Figure 2.

[Click image to view at full size]

Figure 2: Choose LoginName as an existing member to bind to.

Right-click the (ReturnValue) property name and choose Commands if it's not already selected. You should now see a Promote Bindable Properties link at the bottom of the Properties window. Click the Promote Bindable Properties link. A default value is placed in the Return Value property. Click the ellipse next to the Return Value property; this brings up the Bind Property window again. Choose ValueReturned from the list under Workflow1; see Figure 3. The Parameters properties for InvokeSimpleWebService look like Figure 4.

[Click image to view at full size]

Figure 3: Select the ValueReturned property.

[Click image to view at full size]

Figure 4: Parameters property with ReturnValue and UserName set.

Drag a Code activity onto the Workflow Designer before the InvokeSimpleWebService activity. Call this Code activity BeforeInvokeCode, generate Handlers for the activity, and add the following code to the sub generated:

MsgBox("Before Invoke: " & ValueReturned)


This displays a message box with the value of blnReturn prior to the web service being called. Next, drag a Code activity onto the Workflow Designer after the InvokeSimpleWebService. Call this Code activity AfterInvokeCode, generate Handlers for the activity, and add the following code to the sub generated:

MsgBox("After Invoke: " & ValueReturned)

Execute the workflow, and you'll see the Before box appear with False and the After box appear with True. This shows that the workflow called out to the web service providing the variable LoginName as a parameter, and received the parameter ValueReturned back.

There's little change between the Sequential workflow and the State Machine workflow. The only difference is that the InvokeWebService activity must be placed inside an EventDriven activity, like any other activity within a State Machine workflow. Also, the logic behind the code is the same between VB and C#.

Workflow as a Web Service

Using the WebServiceInput, WebServiceOutput, and WebServiceFault activities, you can expose your workflow as a web service. This has some advantages, especially within SOA environments and when deploying a Windows-based application instead of a web-based application. In this section, I present an example of a simple workflow that's exposed as a web service. First, create a VB Sequential Workflow Library called "VBAsWebServiceSequentialLibrary."

Make sure you select Sequential Workflow Library. Change the name of the Workflow1.vb file to "WorkflowAsService.vb." Open the workflow file (WorkflowAsService.vb) and view the code. Add Public ValueEntered As Integer to the workflow class declaration. This variable holds the inputted value and allows manipulation of it. Next, you must define the interface that will be exposed. An interface is what other applications wanting to use this web service will see. It defines any methods or properties that other applications can use to interact with the web service, and is a core OOP concept. To define the interface, add the following:

Public Interface IWorkflowAsWebService
    Function AcceptValue(ByVal InputValue As 
                       Integer) As Integer
End Interface

Any application wanting to use this web service will see only the AcceptValue method, and will see that this method expects a parameter that is of type Integer. Next, view the designer and add a WebServiceInput activity to the workflow. Leave the default name, but click the ellipse next to Interface Type. This displays a window that lets you pick a .NET Type. You want to select the interface that was just defined. You can do this by clicking the Current Project folder on the left and selecting the defined interface, as in Figure 5.

[Click image to view at full size]

Figure 5: Select the newly defined IWorkflowAsService interface.

Set IsActivating to True, because the first WebServiceInput activity within a workflow must have the IsActivating property set to True. From the drop-down list next to the Method Name property, choose AcceptValue. This links the call to the WebServiceInput activity to the interface. When an application using this web service makes a call to this web service and executes AcceptValue, the workflow engine will know to call this WebServiceInput activity. Finally, from the drop-down next to InputValue under the parameters, select IntInputValue. Click the Promote Bindable Properties link at the bottom of the Properties window. Click the ellipse next to the InputValue property and choose ValueEntered from the Bind Properties dialog box. This ties the value passed in as a parameter to AcceptValue to the ValueEntered variable defined within the workflow. The properties of the WebServiceInput activity look like Figure 6.

[Click image to view at full size]

Figure 6: Properties for the WebServiceInput activity.

Add a WebServiceOutput activity to the workflow. Leave the name as the default. Use the drop-down next to InputActivityName to select WebServiceInputActivity1. This property ties the two activities together, so the input activity is receiving information, the output is sending the information, and it's the same information. Click the Promote Bindable Properties link at the bottom of the Properties window. Click the ellipse next to the Return Value property and choose ValueEntered from the Bind Properties dialog box. Again, this ties the value returning to the application that calls this web service to the variable declared within this class.

Next, click GenerateHandlers at the bottom of the Properties window. This generates code to be executed when the activity is executed. When the sub is created, add:

IntInputValue = IntInputValue + 10

This simply adds 10 to the value provided by the calling application. Now the workflow is complete. The workflow will accept a value, add 10 to that value, and return it to the calling application. This simple example shows how you can use a workflow as a web service.

The final step to make a workflow into a web service is to publish the workflow as a web service. To do this, right-click the project name within the Solution Explorer and choose Publish as Web Service. A solution is created within the Solution Explorer, and all the necessary files are also created. To view the created web service, right-click the file with the .asmx extension (VBAsWebServiceSequentialLibrary.WorkflowAsService_Web-Service.asmx) and choose View In Browser. This opens the .asmx file in the browser. Click the AcceptValue link to test the AcceptValue method. Enter 10 as the InputValue and click the Invoke button. The result of 20 appears in the XML file. This shows the workflow working as a web service.

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.