Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Using Windows Workflow to Control ASP.NET Navigation

Windows Workflow is not only ideal for defining page-flow logic visually, but also for letting different systems communicate.

his article describes one simple solution for achieving interoperability between Windows Workflow (WF) and ASP.NET. It leverages the power of WF's powerful visual logic to design page-flow based on user choices. Without WF, enforcing page flow would most likely entail hard-coding such logic. First, the article covers the three main tasks involved in building the solution: creating the Workflow side, writing a middle bit—a service layer—which involves writing an interface, and building the ASP.NET side. Then it provides a step by step walkthrough that describes how to create the solution. To follow along, you must have installed Visual Studio 2005, the Web Application project for Visual Studio 2005, and .NET Framework 3.0, which includes Windows Workflow.

How WF Communicates with ASP.NET
Everything in a workflow is an activity. An activity communicates with the outside world through a Workflow Service. The activity tells the service what it wants. For example, it might ask a service for the user's name and email address, after which it waits for a response.

ASP.NET code responds to events fired from this service, redirecting the user to an appropriate page with input fields for the name and address. When the user has filled out the page and submitted the data back to the server, ASP.NET fires an event that lets the WF service know that a response is available.

In this scenario, the relevant data is stored in a simple dictionary, passed between WF, ASP.NET, and the service layer in serialized form.

I'll describe the service layer first, as that's the code that requires the most work. I'll then describe what you need to do on the WF side and the ASP.NET side to get all the parts talking to each other.

The Service Layer
WF activities communicate with things outside the workflow by using Workflow Services. A service is described by its interface. In this case, you need an interface with one method and one event. The WF activities will call the interface method to request data, and subscribe to the interface event to know when data has been received.

Here's an IGenericInformationService interface that defines the example service. This interface provides most of what WF needs to operate, as you'll see later in this article:

[ExternalDataExchange] public interface IGenericInformationService { string InformationName { get; set; } event EventHandler InformationReceived; void RequestInformation( string informationName ); }

As you can see, the preceding interface has one property, one event, and one method, making it a rather simple service, but one that has everything you need to request and receive information. Note that this interface is used solely by WF, and that WF doesn't care what happens within an implemented version of the RequestInformation method or what code fires the InformationReceived event.

Of course, you must supply an implementation of the above interface. Listing 1 shows a GenericInformationService class that implements the IGenericInformation interface.

In addition to implementing the IGenericInformationService, the GenericInformationService class also adds another event, InformationRequested and another method, SubmitInformation. Both WF and the ASP.NET code will use this class; the WF activity will call RequestInformation and wait for the InformationReceived event. ASP.NET will wait for the InformationRequested event and will call SubmitInformation when the user has filled it in.

Note that the InformationReceived event uses a GenericInformationEventArgs class, defined as:

[Serializable] public class GenericInformationEventArgs : ExternalDataEventArgs { Dictionary _propertyBag; public Dictionary PropertyBag { get { return _propertyBag; } set { _propertyBag = value; } } public GenericInformationEventArgs( Guid instanceId, Dictionary propertyBag ) : base( instanceId ) { _propertyBag = propertyBag; } }

GenericInformationEventArgs is a simple class that exposes a property bag (Dictionary) and extends the ExternalDataEventArgs class defined in System.Workflow.Activities.

The Workflow Side
Remember that everything in a Workflow is based on an activity. To control page flow with WF you create activities that ask for information, activities that wait for data, and activities that perform some logic based upon the returned data.

The activities use a service to request and receive data. WF ships with an existing service called the ExternalDataExchangeService. This is really a container of other services, one of which will be ours—the GenericInformationService described in the previous section.

The ASP.NET side
The ASP.NET application will use the GenericInformationService to wait for an event (the InformationRequested event) that signifies WF is requesting information. Based on the InformationName, it will decide what page to display to the user. When the user has filled in the appropriate page, the information is submitted back to the service using the SubmitInformation method.

Author's Note: Installing .NET 3.0 should install Workflow Performance Counters, but there are some situations where that doesn't happen. If they are not installed WF throws an exception to the effect that a counter cannot be opened. Reinstalling .NET 3 fixed it for me.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date