Docstoc

WorkFlows

Document Sample
WorkFlows Powered By Docstoc
					Developer Introduction to Workflows for Windows
SharePoint Services 3.0 and SharePoint Server 2007
Summary: Get a high-level overview of how Microsoft Windows SharePoint
Services 3.0 implements the workflow capabilities of the Windows Workflow
Foundation, and how Microsoft Office SharePoint Server 2007 extends those
capabilities with symmetrical Microsoft Office InfoPath 2007 forms. (28 printed
pages)
Applies to: Microsoft Windows SharePoint Services 3.0, Microsoft Office SharePoint
Server 2007
Contents
      Introduction to Workflows
      Workflow Architecture
      Workflow Types
      Workflow Composition
      Workflow Markup
      Workflows in Windows SharePoint Services and SharePoint Server 2007
      Authoring SharePoint Workflows
      Authoring SharePoint Workflows in Visual Studio 2005
      Authoring SharePoint Workflows in SharePoint Designer 2007
      Comparing the Visual Studio 2005 Designer for Windows Workflow
       Foundation and SharePoint Designer 2007
      Workflow Structure in Windows SharePoint Services
      Using the Workflow Namespace
      Conclusion
      Additional Resources

Introduction to Workflows
Microsoft Windows SharePoint Services provides a robust, customizable work
environment for users to create, collaborate, and store valuable business
information. Now, with Microsoft Windows SharePoint Services 3.0 and Microsoft
Office SharePoint Server 2007, you can attach custom business processes to these
documents or list items.
You can represent these custom business processes by using workflows. A workflow
is a natural way to organize and run a set of work units, or activities, to form an
executable representation of a work process. This process can control almost any
aspect of an item in Windows SharePoint Services, including the life cycle of that
item. The workflow is flexible enough to model both the system functions and the
human actions necessary for the workflow to complete.
You can create workflows that are as simple or complex as your business processes
require. You can create workflows that the user initiates, or workflows that
Windows SharePoint Services automatically initiates based on some event, such as
when an item is created or changed.
Suppose you need to create a simple workflow that routes a document to a series
of users for approval or comments. This workflow would include actions that the
system needs to perform, as well as provide interfaces for the users to interact with
the workflow in prescribed ways. For example, Windows SharePoint Services would
send an e-mail message to the selected users when the document was ready for
review. Those users would then need to be able to notify Windows SharePoint
Services when they had completed their reviews and, optionally, enter any
comments. The workflow framework included in Windows SharePoint Services 3.0,
and extended in SharePoint Server 2007, enables you to model such complex work
processes and present them to end users in an easily understood, unobtrusive
manner that guides them through each step of the process.
This article provides a high-level overview of workflows as they are implemented in
Windows SharePoint Services and extended in SharePoint Server. It includes a
discussion of the developer tools available to create workflows in both
environments, and the respective capabilities and advantages of those tools.

Workflow Architecture
The workflow functionality in Windows SharePoint Services 3.0 is built on the
Windows Workflow Foundation (WF), a Microsoft Windows platform component that
provides a programming infrastructure and tools for development and execution of
workflow-based applications. WF simplifies the process of asynchronous
programming to create stateful, long-running, and persistent workflow applications.
The WF run-time engine manages workflow execution and allows workflows to
remain active for long periods of time and to survive restarting the computer. Run-
time services offer functionality such as transactions and persistence to manage
errors gracefully and correctly.
The WF run-time engine provides the services that every workflow application
needs, such as sequencing, state management, tracking capabilities, and
transaction support. The WF run-time engine serves as a state machine responsible
for loading and unloading workflows, as well as managing the current state of any
workflows that are running. WF allows any application process or service container
to run workflows by hosting WF — that is, loading WF within its process.
Windows SharePoint Services hosts the WF run-time engine. In place of the
pluggable services that are included with WF, Windows SharePoint Services
provides custom implementations of the following services for the engine:
transaction, persistence, notifications, roles, tracking, and messaging. Developers
can then create workflow solutions that run within Windows SharePoint Services.
Figure 1 shows the workflow architecture in Windows SharePoint Services. Windows
SharePoint Services hosts the WF run-time engine within its process, and provides
custom implementations of the necessary services. The functionality of the WF run-
time engine, as well as the hosting functionality Windows SharePoint Services
provides, is exposed through the Windows SharePoint Services object model.
Figure 1. Workflow architecture in Windows SharePoint Services 3.0




Windows Workflow Foundation also provides the Visual Studio 2005 Designer for
Windows Workflow Foundation, an add-in hosted within the Microsoft Visual Studio
2005 development system that enables developers to create their own custom
workflows and workflow activities. For more information, see Authoring SharePoint
Workflows in Visual Studio 2005.
SharePoint Server employs the workflow functionality in Windows SharePoint
Services 3.0, and extends that functionality through integration with InfoPath
forms, and additional workflow activities. This is discussed in greater detail
in Authoring SharePoint Workflows in SharePoint Designer 2007.
The Windows Workflow Foundation run-time engine is available as part of
the Microsoft Windows Workflow Foundation Runtime Components Beta 2.2 and
Visual Studio 2005 Extensions for Windows Workflow Foundation Beta 2.2 download
available on the Microsoft Download Center. This download also contains the Visual
Studio 2005 Designer for Windows Workflow Foundation, as well as the Windows
Workflow Foundation Software Development Kit (SDK).
Now that we have briefly described the workflow infrastructure provided in Windows
SharePoint Services, let's examine the internal composition and structure of a WF
workflow itself. After that, we'll take a look at the various developer tools Microsoft
provides for creating workflow solutions for Windows SharePoint Services and
SharePoint Server 2007.
Workflow Persistence
One of the most important services Windows SharePoint Services provides to the
WF workflow engine is that of persistence. Workflows that include human
interaction are inherently long running; even in ideal circumstances, humans
require a relatively long time to complete work compared to machines. In many
Microsoft Office scenarios, workflows typically require days, if not longer. Consider
the example workflow that routes documents for approval. The approver might
need several days to review the document.
Clearly, leaving each running workflow in memory for the entire duration of its
execution is not feasible; very soon the resources required by accumulated long-
running workflows would bring the system to a halt.
Instead, after a workflow instance has reached a point at which it is waiting for user
input, Windows SharePoint Services unloads that workflow instance from memory
and persists its data. Then, when an appropriate event, such as the user entering
input, requires that the workflow instance start again, Windows SharePoint Services
re-creates the workflow instance using the persisted data, so the workflow instance
can receive and handle the event as necessary.
Although numerous workflow instances may run at any given time, only a fraction
of those workflows are likely to be in memory and use system resources.

Workflow Types
Windows Workflow Foundation supports two fundamental workflow styles:
      Sequential workflows Represents a workflow as a procession of steps
       that execute in order until the last activity completes. However, sequential
       workflows are not purely sequential in their execution. Because they can
       receive external events and include parallel logic flows, the exact order of
       activity execution can vary.
      State machine workflows Represents a set of states, transitions, and
       actions. One state is denoted as the start state, and then, based on an event,
       a transition can be made to another state. The state machine can have a
       final state that determines the end of the workflow.
You can create workflows of either type for Windows SharePoint Services and
SharePoint Server.
Sequential Workflows
Sequential workflows can best be represented graphically as a flowchart of actions,
with a beginning, an end, and a sequential flow direction from start to finish.
Sequential workflows can incorporate flow structures such as repetition, looping,
and parallel branches, but ultimately progress from the initial action to the final
action.
For example, suppose you were to chart the simple workflow that routes a
document in Windows SharePoint Services for approval. When the workflow starts,
the system notifies the specified reviewer, by e-mail message, that he or she has a
document to review. The reviewer then reviews the document and notifies the
system that the task is completed and whether the reviewer approves or rejects the
document. Based on the reviewer response, the workflow executes one of two
parallel branches. If the reviewer approved the document, the system moves the
approved document to a specific SharePoint document library and then sends an e-
mail message to the entire team notifying them of the approved document. If the
reviewer rejects the document, the system notifies the document author. In either
case, the workflow then reaches its end and terminates. Figure 2 shows this
workflow.
Figure 2. Conceptual diagram of a sequential workflow




State Machine Workflows
Unlike sequential workflows, state machine workflows do not have a prescribed
execution flow, and need not have an end. Instead, state machine workflows define
any number of states which an item may inhabit, and the events that transition the
item from one state to another.
Figure 3 represents a simple document publishing process, modeled as a state
machine workflow. The workflow is initiated when a document is created, and ends
when the document state is set as completed. In between, however, the document
does not travel in a predetermined path, but instead transitions from state to state
as events occur.
The state machine workflow is composed of state activities. Each state activity
represents a state for the item. Each state activity can contain optional state
initialization, state finalization, and one or more event handlers. Each event handler
activity can handle one event. In response to the event handled, some processing
can be done, and a transition can be made to another state.
Figure 3. Conceptual diagram of a state machine workflow




One characteristic of both sequential and state machine workflows is that each type
of workflow can be broken into a collection of discrete actions—those performed by
the system and those taken by users. You can consider these actions to be the
building blocks of workflows. In WF workflows, these actions are referred to
as activities.
Workflow Composition
Earlier, we defined a workflow as a way to organize and run a set of work units, or
activities, to form an executable representation of a work process. Therefore, each
WF workflow consists of a set of related activities. An activity is the elemental unit
of modeling, programmability, reuse, and execution within Windows Workflow
Foundation. An activity may be performed by the system or by a user. For example,
the system may send someone an e-mail message as an alert; or a person might
approve a document for distribution.
Conceptually, our sequential workflow example includes five activities:
      Send e-mail message to notify approver
      Approve or reject document
      Move document to "Approved" document library
      Send e-mail message to notify team
      Send e-mail message to notify document author
Activities can also represent logical control structures that define scope and direct
the execution flow of the workflow, much as code logic controls, such as If
Then and Do While loops, control the program flow in code.
Activities can have properties, methods, and events. Simple activities perform a
single unit of work, such as "delay for 1 day" or "invoke Web service." Composite
activities contain other activities; for example, a conditional with two branches. You
can also attach handlers, such as error or compensation handlers, to activities. This
is especially advisable for composite activities.
In essence, the workflow itself is simply a composite activity that contains all the
other activities in that workflow.
Therefore, workflow can be seen as a set of activities stored as a model that
describes a real-world process. Work passes through the model from start to finish,
and activities might be executed by people or by system functions. Workflow
provides a way of describing the order of execution and dependent relationships
between pieces of short-running or long-running work.
Windows Workflow Foundation includes a number of predefined activities that you
can use in your workflows, or you can create your own custom activities. The
Windows SharePoint Services workflow project template pack contains numerous
activities designed explicitly for use in the Windows SharePoint Services
environment. The template pack also contains the references necessary to program
against the Windows SharePoint Services object model. Similarly, the SharePoint
Server project template pack is customized for use in the SharePoint Server
environment. For more information, see Authoring SharePoint Workflows in Visual
Studio 2005.
Workflow Markup
Each WF workflow can be represented by the following combinations of files:
      An XML file, or markup file, that includes the declarative metadata of the
       workflow
      The markup file, in combination with a code-behind file that contains custom
       code representing the properties and behavior of the workflow
      A code file (or files) that include both the declarative logic and behavior of
       the workflow
The markup file is written in Extensible Application Markup Language (XAML), which
has a published schema to which the file must adhere, and given a file extension of
.xoml.
Because the XAML has a published schema, you can create XAML files using any
text or XML editor you choose. However, the two workflow authoring tools
discussed in this article, the Visual Studio 2005 Designer for Windows Workflow
Foundation and Microsoft Office SharePoint Designer 2007, provide developers with
a graphical interface in which to create workflows and automatically generate the
appropriate markup file.
Developers can choose to integrate or separate their declarative metadata from the
business logic included in the workflow. Conceptually, the "code separation"
paradigm that WF workflows employ is similar to that used in Microsoft ASP.NET:
declarative metadata is separate from the file that encapsulates your business
logic. So although the markup file contains the metadata for the activities included
in the workflow, the properties and behaviors of those activities are detailed in a
separate file.
For workflows authored using code separation, information is persisted in the
markup file, as detailed previously, and in one of the following two types of files:
      A code-beside file, which contains the code that encapsulates your business
       logic. This file may be written in either Microsoft Visual C# or Microsoft Visual
       Basic .NET.
      A workflow rules file, which encapsulates your business logic in declarative
       rules, rather than code.
Each workflow created this way is actually a unique Microsoft .NET type,
constructed from two partial classes, which are represented by the XOML and a
code-behind or rules file. When the workflow project is compiled, these two partial
classes are combined into a .NET assembly. This is the approach you take when
authoring workflows for Windows SharePoint Services or SharePoint Server by
using the Visual Studio 2005 Designer for Windows Workflow Foundation.
Workflows composed only of code files follow the same general compilation process
— that is, the code files are compiled into a .NET type.
In addition, you can compile workflows composed solely of markup files. However,
this is not necessary; the WF run-time engine can load and run uncompiled markup
workflows. This is the approach you take when authoring workflows for Windows
SharePoint Services or SharePoint Server by using SharePoint Designer 2007.

Workflows in Windows SharePoint Services and SharePoint Server 2007
So far, we have discussed the attributes of workflows for any application that
implements the Windows Workflow Foundation. Now, let's take a closer look at
workflows as they are implemented in Windows SharePoint Services specifically and
discuss important aspects of that implementation.
Workflow Templates and Instances
In Windows SharePoint Services, workflows that are available on a site or list are
referred to as workflow templates; a workflow that is actually running on a specific
SharePoint item is called a workflow instance. So, on a given list, several instances
of the same workflow template may be running at the same time, each on a
different SharePoint item. More than one workflow can be running on a given
SharePoint item at a time.
You can run workflows on documents or list items. You make a workflow template
available on a site through a process called association, discussed later in this
article.
Using Forms to Enable User Interaction with Windows SharePoint Services
Although you can use Windows SharePoint Services workflows to model any
number of unique business processes, there are several common stages at which
user can interact with the workflow template or instance.
For the user to pass information to the workflow, the developer must provide an
interface for that interaction through the use of a form. Adding forms to workflows
enables you to make your workflows more dynamic and flexible. Forms enable you
to gather information from users at predefined times in the life of a workflow, as
well as let users interact with the tasks for that workflow.
Technically, you can employ any forms technology with WF workflows, as long as
your forms are capable of doing the following:
      Invoking the Windows SharePoint Services object model
      Generating the data necessary to send to the Windows SharePoint Services
       object model
      Receiving and parsing the required data from the Windows SharePoint
       Services object model
Any information passed to the form on load is formatted as a string, as is the data
the form must pass back to the Windows SharePoint Services 3.0 object model
when the user submits the form. Although this string is typically XML, you can use
any data format that can be formatted as a string, as long as your form is able to
generate strings in that format and parse strings it receives.
Windows SharePoint Services supports the use of ASP.NET 2.0 forms. How these
forms are implemented depends on whether the developer uses the Visual Studio
2005 Designer for Windows Workflow Foundation or SharePoint Designer 2007 as
the workflow authoring tool. In addition, SharePoint Server 2007 offers developers
the ability to integrate Microsoft Office InfoPath forms with their workflows. These
InfoPath forms can be hosted within the Microsoft Office client applications, such as
Microsoft Office Word, Microsoft Office PowerPoint, Microsoft Office Excel, and
InfoPath, as well as the client browser, and provide a richer client experience. For
more information about how each workflow authoring tool implements workflow
forms, see ASP.NET Forms in Windows SharePoint Services Workflows, InfoPath
Forms in SharePoint Server Workflows, and ASP.NET Forms in SharePoint Designer
Workflows.
Whatever forms technology is used, the conceptual operation of each form is the
same. Windows SharePoint Services displays the form to the user at the
appropriate juncture in the workflow. The user enters information, and submits the
form.
As workflow developer, you are responsible for programming what happens when
the user submits a form. In most cases, your form calls into the Windows
SharePoint Services object model and invokes the appropriate method to pass the
form information to the correct workflow instance.
The information string can be in any format, provided that both the form and the
workflow activity are programmed to parse the string. In most cases, developers
will likely choose to use XML.
Windows SharePoint Services passes the string information to the WF run-time
engine, the workflow instance, and ultimately the correct activity within the
workflow instance. The activity receiving the information can then respond as
programmed. Figure 4 shows how a form integrates with workflow.
Figure 4. Form integration with workflow
Three types of forms are used in Windows SharePoint Services workflows:
      Association and initialization forms Association and initialization forms
       are displayed for users to fill out before any workflow is actually started. You
       can use these forms to enable users to set parameters and other information
       for the workflow before it starts.
      Modification forms Modifications are options you present to users to
       change the workflow as it is running on an item. You can then create
       modification forms that enable users to specify the parameters of the
       modification.
      Task forms You can also specify custom forms for the tasks in your
       workflow, based on the workflow task type. Each workflow task type in
       Windows SharePoint Services is assigned a content type; the content type
       definition determines whether a custom form is specified for a given workflow
       task type.
These three types of forms represent the predefined stages at which users can
interact with the workflow. We discuss these stages next.
Points of User Interaction with Workflows
Let's look more closely at the various stages at which users can interact with
workflows in Windows SharePoint Services and SharePoint Server.
Association
Association occurs when a site administrator makes the workflow template available
on a specific document library, list, or content type. At this stage, the site
administrator customizes the workflow for this specific document library, list, or
content type by specifying the following parameter information:
      A unique name for the workflow
      How the workflow is applied to a given item: either automatically when the
       item is created or changed, or manually; and which roles, such as
       Administrator or Contributor, can start a workflow
      The Task list, in which the workflow can create tasks
      The History list in which the workflow can store history events, as defined by
       the workflow
In addition, the workflow developer can enable the site administration to further
customize the workflow by setting parameter information specific to the particular
workflow. The administrator may have to specify parameters, default values, and
other information for the workflow as it applies to items on the list, library, or
content type with which the administrator is associating it.
Associating a workflow actually occurs outside the workflow itself; no workflow
instance is actually started during association. Rather, Windows SharePoint Services
stores the association information in a special internal workflow association table.
Then, when the workflow instance is actually started, Windows SharePoint Services
uses the association data (and the initiation data, if any) to set the parameters of
the new workflow instance.
Initiation
Whereas association deals with the workflow as it applies to a specific list, library,
or content type, initiation deals with the workflow as it applies to a specific
SharePoint item.
Initiation occurs when a user actually starts a workflow instance on a specific item.
The user supplies information custom to that specific workflow on that item, if
necessary, and then starts the workflow.
Workflow developers can use initiation to let users override or append the
association parameters set by administrators, or specify additional parameters or
information about the workflow as it applies to the given SharePoint item. Not all
workflows need initiation. In fact, a workflow set to start automatically cannot have
initiation parameters.
The Windows SharePoint Services workflow project for the Visual Studio 2005
Designer for Windows Workflow Foundation includes an activity that acts as the
event handler when the workflow is initiated. This activity is the first activity in any
Windows SharePoint Services workflow.
Modification
Modifications enable users to alter the parameters or flow of a workflow instance as
it is running. As a developer, you may have points in your workflow at which you
would like to enable users to alter the workflow while it is running on an item. For
example, you might want to enable a user to assign a task to another person, or
even add a specific task to the workflow. The options you present to users to
change the workflow as it is running on an item are called modifications.
The Windows SharePoint Services workflow project for the Visual Studio 2005
Designer for Windows Workflow Foundation includes an activity to enable a
workflow modification, as well as an activity that acts as an event handler when a
workflow modification is enabled.
Tasks
Workflow activities that are performed by people are represented as tasks in
Windows SharePoint Services workflows.
As workflow author, you can specify the task schema. For example, the task listing
could include the following:
      Task title
      Name of person to whom the task is assigned
      Task status
      Task priority
      Task date due
      A link to the referenced item
The user can then edit the task as necessary. The workflow instance is notified of
changes to workflow tasks and can choose to respond to them as specified in the
workflow.
The Windows SharePoint Services workflow project for the Visual Studio 2005
Designer for Windows Workflow Foundation includes activities that create, delete,
and update tasks, as well as activities that act as event handlers when tasks are
created, updated, or deleted.

Authoring SharePoint Workflows
Microsoft provides two development tools for authoring workflows for Windows
SharePoint Services: the Visual Studio 2005 Designer for Windows Workflow
Foundation, and Office SharePoint Designer 2007. Because each authoring tool
produces workflows with different attributes and capabilities, it is worth examining
each tool in detail.
Figure 5 shows the various steps that need to be performed to create, deploy,
associate, and run a workflow with each of the authoring tools. In general, the
largest differences between the two tools are the following:
      Workflow authoring in the Visual Studio 2005 Designer for Windows Workflow
       Foundation is performed by a professional developer, who creates a workflow
       template that can be deployed across multiple sites and contains custom
       code and activities. The developer then passes the workflow template to a
       server administrator for actual deployment and association.
      Workflow authoring in SharePoint Designer is likely done by someone other
       than a professional developer, such as a Web designer or knowledge worker,
       who wants to create a workflow for a specific list or document library. In this
       case, the designer is limited to the workflow activities on the Safe Controls
       List, and the workflow cannot include custom code. The workflow author
       deploys the workflow template directly to the list or document library as part
       of the workflow authoring process.
For a detailed comparison of the capabilities of the two tools, see Comparing the
Visual Studio 2005 Designer for Windows Workflow Foundation and SharePoint
Designer 2007.
Figure 5. Workflow authoring, deployment, and initiation process




Authoring SharePoint Workflows in Visual Studio 2005
The Visual Studio 2005 Designer for Windows Workflow Foundation is an add-in for
Visual Studio 2005. It provides a means to rapidly develop workflows by using a
graphical interface that leverages a developer's knowledge of the Visual Studio
development environment.
Visual Studio 2005 Designer for Windows Workflow Foundation is a tool for you to
rapidly create the workflow in a way that is integrated with the development of the
code encapsulating your business processes. To do this, the Visual Studio 2005
Designer for Windows Workflow Foundation provides a graphical interface with
intuitive controls, hosted within the familiar Visual Studio development
environment. Its features include the following:
      A drag-and-drop design surface that lets you assemble custom workflows
       from predefined workflow activities you drag from the Toolbox
      An interface that lets you work on your workflow markup using intuitive
       graphical tools
      Integration with the Properties window, so developers can configure
       properties of workflow activities either through the graphical interface or
       directly in the code-beside file, and always keeps the two in sync
      Debugging of your workflows by attaching to the Windows SharePoint
       Services process, including setting breakpoints in your workflow
      The ability to attach error, compensation, and event handlers to activities,
       and "comment out" activities graphically
The Visual Studio 2005 Designer for Windows Workflow Foundation is available as
part of the Microsoft Windows Workflow Foundation Runtime Components Beta 2.2
and Visual Studio 2005 Extensions for Windows Workflow Foundation Beta
2.2 download on the Microsoft Download Center. This download also contains the
Windows Workflow Foundation run-time engine, as well as the Windows Workflow
Foundation SDK.
To further assist your workflow development, Microsoft provides two Visual Studio
project template packs for use with the Visual Studio 2005 Designer for Windows
Workflow Foundation: one customized for Windows SharePoint Services workflows,
the other customized for creating workflows for SharePoint Server.
The Window SharePoint Services workflow project template contains a reference to
the Windows SharePoint namespace and includes custom workflow activities
designed specifically for the Windows SharePoint Services environment. These
custom activities enable you to perform functions common to the Windows
SharePoint Services environment, such as creating, updating, completing, and
deleting SharePoint tasks, sending e-mail, and enabling workflow modifications.
The SharePoint Server workflow project contains everything the Window SharePoint
Services workflow project template, as well as a reference to the SharePoint Server
namespace, and additional functionality for managing workflow tasks in the
SharePoint Server work environment.
The Workflow Development Process in Visual Studio
In general, when you develop workflows for Windows SharePoint Services or Office
SharePoint Server using the Visual Studio 2005 Designer for Windows Workflow
Foundation, you follow these basic steps:
   1. Author your workflow, including the code-beside file if needed, in the Visual
      Studio 2005 Designer for Windows Workflow Foundation.
   2. Design and publish any forms you want to use with your workflow.
   3. Author the feature definition and workflow template definition file, which
      contains information about the workflow assembly, and binds the forms to
      the workflow assembly.
   4. Compile the workflow files into a .NET assembly.
   5. Package the workflow assembly and workflow definition together and deploy
      them by using the features functionality in Windows SharePoint Services.
   6. Debug the live workflow assembly using the Visual Studio 2005 Designer for
      Windows Workflow Foundation.
   7. Recompile and deploy the workflow assembly as necessary to fix any bugs
      found.
The following sections provide an overview of each of these development steps.
Creating Workflows by Using the Visual Studio 2005 Designer for Windows
Workflow Foundation
When you select a new Windows SharePoint Services or Office SharePoint Server
workflow project, Visual Studio displays the Visual Studio 2005 Designer for
Windows Workflow Foundation design surface (Figure 6). This design surface
presents a graphical interface, where you can assemble workflows by dragging and
dropping various activities from the Toolbox.
Figure 6. Visual Studio 2005 Designer for Windows Workflow Foundation
interface




When you drag a specific activity onto your workflow, the Visual Studio 2005
Designer for Windows Workflow Foundation shows you the valid locations for that
activity within the workflow. You cannot place an activity in a location where it
would not be valid. For example, you cannot position a Send activity as the first
activity in a Listen activity branch. As shown in Figure 7, Visual Studio 2005
Designer for Windows Workflow Foundation displays green plus-sign icons to denote
valid positions for the specific activity.
Figure 7. Valid positions for a Workflow activity




As you graphically design your workflow, the Visual Studio 2005 Designer for
Windows Workflow Foundation actually generates corresponding markup.
In addition, if you are working with code separation, your workflow project contains
a code-behind file, in which you program the business logic of your workflow. You
can switch between working in the workflow design surface and the code-beside file
whenever you want.
Setting Workflow Properties
After you add the activity to the workflow, you must set the properties of the
activity for it to be valid within the workflow. You can set these properties by using
the standard Visual Studio Properties window. The type of data you can specify
depends on the type of data the property itself accepts: literal values, variables, or
method names.
If you want to specify a variable for the property, you can either enter the variable
name in the Properties window, in which case the Visual Studio 2005 Designer for
Windows Workflow Foundation automatically declares the variable in the code-
behind file; or declare the variable in the code-behind file, and then select it in the
Properties window.
Certain activity properties are essentially references to methods in the code-beside
file that conform to a specific signature. As with variable names, you can enter the
method name in the Properties window and let the Visual Studio 2005 Designer for
Windows Workflow Foundation add the method signature to the code-behind file, or
you can create the method in the code-behind file and then select the method in
the Properties window.
You can also bind a property to the property of another activity.
Handler Activities
A workflow might have several potential points of failure. It is important to track
the state of a workflow and to report errors as they occur, so that you can resolve
problems accurately and with a minimum of effort. It is equally important for a
workflow to maintain the integrity of a set of closely related actions, so that if part
of an operation takes place but another does not, the entire operation can be rolled
back. You can use
the FaultHandlerActivity, TransactionScopeActivity, CompensationHandlerA
ctivity, andCancellationHandlersActivity activities to handle errors, to maintain
the state of a workflow, and to fix problems as they occur.
You can think of a FaultHandlersActivity activity as a C-language try block, to
which you can attach an ordered set of FaultHandlerActivity activities that act as
exception handlers. These exception handlers can be thought of as C-
language catch blocks. If an exception is thrown during the execution of a
composite activity, the WF run-time engine matches the exception against the
exception types that are handled by the FaultHandlerActivity activities. If the
run-time engine finds no matching exception handler, it then communicates the
exception to the next higher composite activity, where the process repeats, and so
on, until an appropriate handler is found.
You can also have EventHandlersActivity activities that respond to events, by
adding event handlers to an EventHandlerScopeActivity activity. Conceptually,
these event handlers are very similar to those in the C or Visual Basic .NET
languages. To create an event handler, you must
use EventDrivenActivity activities.
CompensationHandlerActivity activities contain code that compensates for, or
rolls back, the operations of a composite activity if it does not perform successfully.
ASP.NET Forms in Windows SharePoint Services Workflows
As mentioned earlier, you can use ASP.NET to create the forms you use with your
Windows SharePoint Services workflow. These forms are then displayed in the
Windows SharePoint Services user interface at the appropriate stages in the
workflow.
Workflow forms are late-bound to the workflow assembly through information you
supply in the workflow template definition XML file. The workflow template
definition schema contains elements for denoting the URL of the various types of
forms you can use with Windows SharePoint Services workflows. This provides the
ability to create elements for forms for any custom workflow modifications, as well
as forms for the various types of SharePoint tasks used in the workflow.
In most cases, the workflow assembly itself contains no information about or link to
the workflow forms themselves. Developers can change the workflow forms to be
used just by editing the workflow definition XML, without having to recompile the
workflow assembly itself. The one exception is workflow modifications; each activity
that enables a workflow modification must contain the GUID of the form for that
workflow modification.
InfoPath Forms in SharePoint Server Workflows
Although you can also use ASP.NET workflow forms in SharePoint Server workflows,
SharePoint Server offers you the capability to extend your workflow forms and
display them in Microsoft Office client applications.
You can use InfoPath forms with your workflows. InfoPath gives you the ability to
create symmetrical forms — that is, forms that look and operate exactly the same
whether they are displayed in the SharePoint Server Web interface or within a
Microsoft Office client application, such as Word, Excel, or PowerPoint. This provides
a richer interaction experience in which the user can interact with the workflow
directly in the client application, rather than having to leave the client and switch to
the SharePoint Server Web interface. And as a developer, you don't have to create
two separate forms, one for use on the server and one for use in the client, to
provide the user with this client application integration.
For more information about creating symmetrical forms in general, refer to the
Microsoft Office InfoPath 2007 client help or Office Online.
SharePoint Server uses Office Forms Services, a server-based run-time
environment for InfoPath forms, to host workflow forms. Office Forms Services
consumes the forms you create in the InfoPath client application and renders them
in an ASP.NET framework, which acts as a run-time environment for the form. This
environment presents a form editing experience that matches the InfoPath client
application.
For more information about Office Forms Services, see the Microsoft Office
SharePoint Server 2007 SDK.

 Note:

Because Office 2007 client applications such as Word, PowerPoint, and Excel include
functionality for hosting InfoPath forms, the user does not need to have the InfoPath client
application installed to take advantage of this rich integration.
Displaying InfoPath Workflow Forms
SharePoint Server uses the same basic technique to display all custom InfoPath
workflow forms, including association, initiation, modification, or edit task forms.
When the user clicks a link to display a workflow form in the SharePoint Server
interface, SharePoint Server loads an ASPX page that contains an Office Forms
Services Web Part. This Web Part then converts the appropriate InfoPath form into
ASP.NET and loads it. When the user submits that form, the Web Part receives the
data from the form and handles it accordingly.
The ASPX pages that contain the Office Forms Services Web Part are included in
SharePoint Server.
Specifying InfoPath Workflow Forms
Again, you specify the custom forms you want to use in the workflow template
definition, rather than the workflow itself. In most cases, this involves setting two
elements. First, you set the form URL for that workflow process (association,
initiation, modification, and so forth) to the appropriate ASPX hosting page included
with SharePoint Server. Next, you add an element specifying the URN for the
custom InfoPath form for that type of workflow process.
Submitting Information by Using InfoPath Workflow Forms
For the hosting ASPX page to receive data from the hosted form, the developer
adds a Submit button to the InfoPath form. This button uses a rule to submit data
by using the data connection to the hosting environment. This connection passes
the data back to the hosting ASPX page automatically when the user clicks
the Submit button. The hosting ASPX page then handles parsing the data and
passing it back to the workflow or document library, as appropriate.
Deploying Workflows
When you are finished specifying your workflow, you can choose to compile your
workflow as a workflow, or as an activity.
After you have compiled your workflow, you can use the SharePoint Features
functionality to package and deploy the workflow assembly and any necessary
supporting files.
Feature packaging is a way of encapsulating Windows SharePoint Services solutions
and functionality for ease of deployment. It provides a mechanism by which
developers can package the files needed for a solution, such as workflows, Web
Parts, lists, and site definitions, for ease of distribution and deployment. Developers
package the necessary files into a .wsp file, which is essentially a .cab file
containing a manifest that lists its contents. For more information about SharePoint
Features, see the Microsoft Windows SharePoint Services 3.0 SDK.
Each workflow template you deploy must contain a workflow template definition
file. A workflow template definition is an XML file that contains the information that
Windows SharePoint Services requires to instantiate and run the workflow, such as
the following:
      The name, GUID, and description of the workflow template
      Assembly
      The URLs (or URNs for IP forms) of any custom forms used with this
       workflow template
      Optionally, the names of the workflow, workflow engine, and host service
       assemblies to use when running the workflow
      Optionally, the correct classes within those assemblies to call
The workflow assembly itself must be deployed to the global assembly cache.
After it is deployed to a site, the workflow is available as a workflow template,
which SharePoint administrators can associate with the document libraries and lists
on that site.
Debugging Workflows
After you deploy your workflow assembly, you can debug your workflow by opening
your workflow project and attaching to the Windows SharePoint
Service w3wp process.
Because the Visual Studio 2005 Designer for Windows Workflow Foundation is
hosted within Visual Studio, you can take full advantage of the debugging
capabilities of Visual Studio. You can set breakpoints both in the code you write in
your code-beside file, as well as on workflow activities in the design surface.
  Note:

For ease of debugging, we strongly recommend that you develop your workflow
templates on a server to which you plan to deploy them.
The Visual Studio 2005 Designer for Windows Workflow Foundation not only
supports standard Visual Studio debugging features such as the Breakpoints and
Call Stack windows, it also includes a range of visual indicators that provide
information during the debugging process. You can also add breakpoints to a
workflow activity while you are debugging the assembly.
You can perform step in, step out, and step over operations to move through
workflow code.
The following types of debugging are not supported by the Visual Studio 2005
Designer for Windows Workflow Foundation:
      Just-in-time debugging of run-time exceptions in the hosting process
      Just-in-time debugging by selecting a process in the Task Manager
For more information about debugging using the Visual Studio 2005 Designer for
Windows Workflow Foundation, see the Windows Workflow Foundation SDK.

  Note:

The Windows Workflow Foundation SDK is available as part of the Microsoft
Windows Workflow Foundation Runtime Components Beta 2.2 and Visual Studio
2005 Extensions for Windows Workflow Foundation Beta 2.2 download available on
the Microsoft Download Center. This download also contains the Visual Studio 2005
Designer for Windows Workflow Foundation, as well as the Windows Workflow
Foundation run-time engine.

Authoring SharePoint Workflows in SharePoint Designer 2007
When you author a workflow in Office SharePoint Designer 2007, you are authoring
that workflow directly against and data-binding to, a specific list or document
library in Windows SharePoint Services. You are using a predefined list of workflow
activities and are not using any code. The workflow you design is not compiled as
an assembly; it is stored as source files until Windows SharePoint Services compiles
it the first time it runs.
Such an approach has several advantages:
      Workflows can be developed and tested rapidly.
      Because the workflow is specific to a given list, the deployment process is
       much less complicated.
      Security issues are much less complicated as well, for the same reason.
      Because they are not compiled into assemblies, workflows created in
       SharePoint Designer can be deployed to servers where administrative policy
       prohibits custom code assemblies.

         Note:

       Workflows authored in SharePoint Designer are assembled from a "safe list"
       of predefined activities, which presumably have been approved by
       administrators to run on the servers.
      Workflows can be created by users with less developer experience, such as
       Web designers or knowledge workers.
This approach also means that workflows authored in SharePoint Designer differ
from those created using the Visual Studio 2005 Designer for Windows Workflow
Foundation in several important ways:
      A workflow authored in SharePoint Designer cannot be deployed to multiple
       lists. It is valid only for the list for which it was created.
      Because you author the workflow directly against a list, the workflow is
       associated with the list at design time. Therefore, workflows authored in
       SharePoint Designer have no association stage.
      Workflow modifications are not available in workflows authored in SharePoint
       Designer.
      You cannot author against a content type in SharePoint Designer.
For a detailed comparison, see Comparing the Visual Studio 2005 Designer for
Windows Workflow Foundation and SharePoint Designer 2007.
Running Workflows Authored in SharePoint Designer 2007
Because they contain no custom code, workflows authored in Office SharePoint
Designer are not compiled and deployed as assemblies. Rather, they are stored as
their source files within Windows SharePoint Services and compiled into memory
only when needed.
For each site, the workflows of this type are stored in a separate document library.
This document library contains a folder for each workflow authored in SharePoint
Designer. The folder contains all the source files necessary for the workflow,
including:
      The workflow markup file
      The workflow rules file
      ASPX forms for any custom workflow forms necessary
Windows SharePoint Services includes a just-in-time compiler to compile the source
files into a workflow the first time that workflow is started on an item. Windows
SharePoint Services retains the compiled workflow in memory against the time it is
called again, similar to how servers keep compiled .aspx pages in memory to speed
execution performance the next time a page is called.
Each time a workflow is started on an item, Windows SharePoint Services
determines whether the workflow was deployed as an assembly or as source files.
If a workflow assembly exists, Windows SharePoint Services calls that assembly to
create the workflow instance. If the workflow was deployed as source files,
Windows SharePoint Services determines whether it already has a workflow
compiled from those source files in memory. If it does, Windows SharePoint
Services calls the in-memory compiled workflow to create the workflow instance. If
not, Windows SharePoint Services uses its just-in-time compiler to compile the
source files into an in-memory workflow, which it then calls to create the workflow
instance.
Workflow Development Process in SharePoint Designer 2007
To aid the rapid design and deployment of workflows, the development process in
SharePoint Designer is much simpler than in Visual Studio.
In general, when you develop workflows for Windows SharePoint Services or
SharePoint Server using the Visual Studio 2005 Designer for Windows Workflow
Foundation, you follow these basic steps:
   1. Author your workflow by assembling and configuring the predefined activities
      and conditions available in SharePoint Designer.
   2. Have SharePoint Designer automatically generate ASP.NET forms for
      workflow initiation and any custom SharePoint task, if necessary.
   3. Customize the workflow forms, if necessary.
SharePoint Designer automatically generates the workflow definition template and
handles the deployment of the workflow to the specified list.
The following sections provide an overview of each of these development steps.
Creating Workflows by Using SharePoint Designer 2007
SharePoint Designer uses a wizard-driven interface that enables users to assemble
sequential workflows from predefined activities. Users select activities from a
predetermined list and configure them using the SharePoint Designer interface.
These activities can be the same activities present in the Visual Studio 2005
Designer for Windows Workflow Foundation; there is no difference in activities
between the two tools.
In SharePoint Designer, however, each activity appears as an action, represented
by a sentence that contains variables that the user can configure using drop-down
menus and look-up dialog boxes. Users can also select conditions, which are
configurable conditional clauses that direct the flow of the workflow.
As the user selects and configures conditions and actions in the workflow interface,
SharePoint Designer generates the two files that actually represent the workflow
class:
      The workflow markup file, which contains markup that describes the activities
       included in the workflow
      The workflow rules file, which contains the business logic of the workflow in
       declarative rules form, rather than code
Adding Custom Activities and Conditions
As noted, workflow designers in SharePoint Designer cannot create custom
activities for use in their workflows. Instead, they are limited to the activities and
conditions that have been made available on the Safe Controls List (presumably
approved by a server administrator) that appears in SharePoint Designer.
A condition is simply a custom assembly with a static method that evaluates some
condition and returns a Boolean when called.
Developers can create custom activities and conditions, and make them available
on the safe list. To do this, developers must:
   1. Create the activity or condition, compile it as a strong-named assembly, and
      deploy it to the global assembly cache.
   2. Add the activity or condition to the action safe list in the web.config file.
   3. In the WSS.Actions file, located in the workflow folder, add rules and
      parameters for the sentence that represents the activity or condition in the
      SharePoint Designer user interface. This is markup that specifies how the
      activity or condition appears and performs in the interface, because this
      information is not present in the activity or condition assembly.
ASP.NET Forms in SharePoint Designer Workflows
You can create an initiation stage for your workflow in SharePoint Designer. If you
do, SharePoint Designer automatically generates an initiation form by using
ASP.NET, according to your initiation specifications.
Similarly, you can create custom SharePoint tasks for your workflow. Again,
SharePoint Designer automatically generates an ASP.NET form for the task,
according to your specifications.
These aspx forms are stored on the SharePoint site with the workflow source files.
You can open and customize them as you would any other aspx form.

  Note:

SharePoint Designer 2007 does not offer integration with InfoPath forms.
Deploying Workflows with SharePoint Designer 2007
Because you author against a specific list, the deployment of workflows created in
Office SharePoint Designer is a much simpler process than workflows created in the
Visual Studio 2005 Designer for Windows Workflow Foundation. SharePoint
Designer handles the deployment of the workflow to the specified list.
SharePoint Designer offers no custom debugging functionality.
Deleting a workflow authored in SharePoint Designer from a list does not delete the
actual source files used to compile that workflow in memory. Rather, the workflow
is no longer associated with the list, but the source files remain stored in the
workflow document library on the site.
In the Windows SharePoint Services object model, workflows authored in
SharePoint Designer are indistinguishable from workflows authored in the Visual
Studio 2005 Designer for Windows Workflow Foundation.

Comparing the Visual Studio 2005 Designer for Windows Workflow
Foundation and SharePoint Designer 2007
The following table offers a detailed comparison between the capabilities offered by
the Visual Studio 2005 Designer for Windows Workflow Foundation and Office
SharePoint Designer 2007, and the workflows you can create with each.
Table 1. Detailed comparison of capabilities
Visual Studio 2005 Designer for
Windows Workflow Foundation                     SharePoint Designer 2007

Can write workflows for Windows                 Can write workflows for Windows
SharePoint Services or SharePoint Server        SharePoint Services or SharePoint
                                                Server
Code-behind file enables developer to write     No code-behind file; workflow rules
custom Visual C# or Visual Basic .NET code      file declaratively encapsulates
to express business logic                       business logic
Generates workflow markup file                  Generates workflow markup file
Workflow is authored as a template, which       Workflow is authored against and
can be associated with multiple sites and       data-bound to specific list at design
lists                                           time
Workflow markup file, or markup and code-       Workflow markup, workflow rules,
behind files, are compiled into workflow        and supporting file are stored,
assembly                                        uncompiled, in a specific document
                                                library on the site
Workflow template must be associated with       Association happens when the
each list on which it is to be available        workflow is authored against the
                                                specific list; no later association is
                                                necessary or possible
Can use any forms technology. For               Automatically generates ASP.NET
example, ASP forms for Windows                  forms, which you can then customize
SharePoint Services workflows, or InfoPath
forms for SharePoint Server workflows
Can include workflow modifications              Workflow modifications are not
                                                available
Can use custom symmetrical InfoPath             InfoPath forms integration not
forms, which enables Office client              available
integration of custom workflow forms
Can author custom activities for inclusion in   Must use activities provided
workflows
Package workflow assembly and workflow          Automatically handles deployment to
definition as a SharePoint feature, and         specific list
deploy to the site
Can use Initiation form to gather           Can use Initiation form to gather
information from the user when starting the information from the user when
workflow                                    starting the workflow
Can use custom forms for users to interact      Can use custom forms for users to
with SharePoint tasks                           interact with SharePoint tasks
Visual Studio debugging available               No step-by-step debugging available
Can author both sequential and state            Can author only sequential workflows
workflows

Workflow Structure in Windows SharePoint Services
Figure 8 shows how the various elements of the Windows SharePoint Services
workflow structure are joined after a workflow template has been created,
deployed, and associated with a specific content type, list, or document library.
When you associate a workflow template with a given content type, list, or
document library, Windows SharePoint Services writes the association parameter
information set by the administrator to a farm-level workflow association table. The
entry in this association table links the specific content type, list, or document
library to the workflow template definition of the associated workflow. The
information in the workflow template definition, in turn, includes references to the
workflow assembly itself, as well as any custom workflow forms the workflow uses.
In the case of workflows authored in SharePoint Designer 2007, the Designer
automatically writes the association parameter information to the workflow
association table, and generates and installs the workflow template definition. Also,
the workflow is stored in a site-level workflow document library, not as a compiled
assembly, but as the markup and workflow rules source files.
Figure 8. Workflow component structure in Windows SharePoint Services




Using the Workflow Namespace
After you deploy your workflow solution, you can use the Windows SharePoint
Services object model to query workflow processes and programmatically perform
workflow actions, such as adding a workflow to a list or starting a workflow for an
item.
Major Microsoft.Windows.SharePoint.Workflow Objects
The Microsoft.Windows.SharePoint.Workflow namespace represents the
workflow functionality contained in Windows SharePoint Services.
The SPWorkflowTemplateCollection object represents the workflow templates
currently deployed on a site. Each SPWorkflowTemplate object represents a
workflow template and contains properties you can use to get or set information
about the template, such as the instantiation data and the history and task lists for
the template.
To associate a workflow with a list or document library, use
the SPList.AddWorkflowAssociation method. This overloaded method takes four
parameters:
      Either the workflow template name or ID
      The name you want to give the workflow
      Either the task list name or ID for the task list you want to use with this
       workflow
      The history list for the workflow
As with adding a workflow through the user interface, this method adds a status
column for the workflow to the list. Use
the SPList.RemoveWorkflowAssociation method to remove a workflow template
from a list.
The SPWorkflowAssociationCollection object represents the internal workflow
associations table for a site; that is, it represents the workflows currently
associated on lists across a site collection, along with the association information for
each. Each SPWorkflowAssociation object represents a workflow template that
has been associated with a specific list, and contains properties that return custom
information about the association, such as whether the workflow is enabled,
whether the workflow has been modified, and the list with which the workflow has
been associated, as well as a reference to the SPWorkflowTemplate object that
serves as a base for this SPWorkflowAssociation object.
The SPWorkflowAssociation.IsDeclarative property returns True for workflows
that are stored as uncompiled files, such as those authored in SharePoint Designer.
The SPWorkflowCollection represents the workflow instances that have run or
are currently running on a given list item. Each SPWorkflow object contains
properties that return information about the workflow instance, such as whether the
workflow has completed, its internal state, and the workflow template on which it is
based. In addition, each workflow contains a collection of the tasks for the
workflow, SPWorkflowTaskCollection.
Use the SPListItem.Workflows property to return
an SPWorkflowCollection object that represents the workflows currently running
for that list item.
Managing Running Workflow Instances Programmatically
Users interact with the workflows running on items individually, through the
Windows SharePoint Services user interface. But Windows SharePoint Services
provides functionality for you to centrally control the running instances of workflows
across your entire server farm through the object model. Use
the SPWorkflowManager object to manage the running instances of workflows
across the entire farm. The SPWorkflowManager object has no equivalent in the
user interface. Although the object is accessed through the SPSite object, you can
use it to administer the workflow instances running on your entire farm. Use
the SPWorkflowManager object to:
      Start, run, or cancel workflows.
      Return all the workflows currently running on a specific item.
      Cancel all workflow instances based on a specific workflow template within a
       list.
      Perform other workflow administration operations.
To manually start a specific workflow for an item (that is, a workflow that is not
configured to start automatically), use
the SPSite.WorkflowManager.StartWorkflow method. This method takes three
parameters: the name of the list item, the name of the workflow template, and the
start event.
Figure 9 shows a hierarchical view of the SPWorkflowManager object and the
objects it contains.
Figure 9. SPWorkflowManager object hierarchy




Conclusion
Windows SharePoint Services 3.0 hosts Windows Workflow Foundation, which
enables you to attach custom business processes, implemented as sequential or
state machine workflows, to SharePoint items. This implementation includes the
ability to create custom workflows, complete with forms integration for user
interaction. SharePoint Server 2007 extends these workflow capabilities by offering
integration with symmetrical InfoPath forms that can be hosted in Office client
applications such as Word, PowerPoint, Excel, and InfoPath.
Microsoft provides two powerful tools for authoring workflows for Windows
SharePoint Services. The Visual Studio 2005 Designer for Windows Workflow
Foundation is an add-in for Visual Studio 2005 that gives you the ability to develop
workflow templates, complete with custom code, which you can deploy to multiple
sites and list. Alternatively, you can use SharePoint Designer to rapidly develop and
deploy list-specific workflows from a predefined list of workflow activities.
In either case, after you deploy your workflow solution, you can use the Windows
SharePoint Services object model to query workflow processes and
programmatically perform workflow actions
Developing Sequential Workflows for
SharePoint Server 2007 Using Visual Studio
2008
Summary: Learn to use Microsoft Visual Studio 2008 to create a Microsoft Office
SharePoint Server 2007 sequential workflow with associated forms and content
types to manage headcount request approvals. (31 printed pages)
Applies to: Microsoft Office SharePoint Server 2007, Microsoft Office InfoPath
2007, Microsoft Visual Studio 2008
Contents
      The Headcount Request Approval Workflow Solution
      Headcount Request Scenario
      Solution Implementation Details
      Headcount Request Workflow Solution Deployment
      Conclusion
      Additional Resources
Download the sample code that accompanies this article: HeadCount Request
Workflow Sample Code

The Headcount Request Approval Workflow Solution
A common scenario in many organizations involves the request to open a new job
position. The process typically is something like this:
   1. A hiring manager decides there is justification to open a new position, and
      submits a new headcount request for approval.
   2. Senior management reviews the headcount request and either approves or
      denies it.
   3. If the headcount request is approved, a new position is opened so that the
      recruiting process can begin.
This article presents a Headcount Request Approval workflow solution that makes
use of the workflow capabilities of Microsoft Office SharePoint Server 2007. You can
use this workflow solution to help manage the headcount request approval process.
The solution uses Microsoft Visual Studio 2008 to create the following:
      A custom Microsoft Office InfoPath 2007 form that hiring managers can use
       to submit headcount requests.
      A SharePoint sequential workflow that manages the state of the headcount
       request, assigns headcount request tasks, and sends notifications to the
       employees involved in the approval process.
      Two SharePoint custom content types that are used to display headcount
       request-specific task editing forms.
      A class library that implements two custom .aspx pages for the Headcount
       Request Workflow's association and initiation forms.

Headcount Request Scenario
The headcount request scenario this article walks you through includes the
following four actions:
      Associating the Workflow with the Document Library
      Submitting a Headcount Request
      Starting the Headcount Request Workflow
      Completing Headcount Request Workflow Tasks
The following sections describe these actions.
Associating the Workflow with the Document Library
One of the key pieces of the headcount request approval solution is an Office
SharePoint Server 2007 document library that is used to store Office InfoPath 2007
Headcount Requests forms. The Headcount Request Workflow needs to be
associated with the document library before the workflow can be run against form
instances in the document library.
The Headcount Request Workflow uses an ASP.NET .aspx page for its association
form. The association form is displayed to the user who is associating the workflow
with the document library, and allows that user to specify the default settings for
the workflow. Figure 1 shows the Headcount Request Workflow association form.
Figure 1. Headcount Request Workflow association form




The form contains three groups of settings:
      Workflow Tasks This single workflow task setting determines how
       headcount request approval tasks are assigned to members of the senior
       leadership team. The choices are parallel and serial assignment. If All
       participants simultaneously (parallel) is selected, headcount request
       review tasks are assigned to all specified senior leadership team members at
       the same time. If One participant at a time (serial) is selected, headcount
       request review tasks are assigned to senior leadership team members one
       after the other, in the order that their names are listed.
      Senior Leadership Team Settings These settings include the names of the
       senior leadership team members who can approve headcount requests, a
       message to display to reviewers, and the number of approvals required for
       the headcount request.
      Operations Team Settings These settings include the names of the
       operations team members who can open a new position for an approved
       headcount request and a message to display to them.
Submitting a Headcount Request
The headcount request approval process begins when a hiring manager decides
there is business justification to request headcount. To start the request approval
process, the manager opens the Headcount Requests SharePoint document library
and chooses to create a request. The Headcount Requests document library is
configured to use the Form content type, with its document template set to the
custom Office InfoPath 2007 Headcount Request form.
Figure 2. Creating a headcount request




The Office InfoPath Headcount Request form is a browser-compatible form template
that is uploaded and activated on the site that contains the Headcount Requests
document library. This allows the form to be hosted in the browser by InfoPath
Forms Services.
Figure 3. Office InfoPath Headcount Request form




The hiring manager fills in the Headcount Request form, and then clicks Save and
Close. The form template uses managed code to generate a unique name by
concatenating the values from the Team and Date fields with the current time. It
then saves the form to the Headcount Requests document library.
Starting the Headcount Request Workflow
The Headcount Requests document library is associated with a SharePoint
sequential workflow. The workflow is configured to allow it to be started manually
on items in the document library. The hiring manager pauses the mouse over the
previously saved Headcount Request form in the Headcount Requests document
library, and on the menu clicks Workflows.
Figure 4. Selecting Workflows menu item
 Visual Basic Note:

The workflow could be configured to start automatically on creation of headcount
requests. However, to demonstrate the use of the workflow initiation form, this
walkthrough assumes that the workflow is not configured to start automatically.
The Headcount Requests Workflows page is displayed, allowing the manager to
start an instance of the Headcount Request Workflow on the Headcount Request
form. The manager selects the Headcount Request Workflow.
Figure 4a. Selecting the Headcount Request Workflow




The Headcount Request Workflow uses an ASP.NET .aspx page as its initiation form.
When an instance of the Headcount Request Workflow is started manually, the
workflow initiation form is displayed. This allows the initiating user to override the
default workflow settings that were specified when the workflow was associated
with the document library. The workflow initiation form is very similar to the
workflow association form. It differs only in that it offers no option for specifying
parallel or serial assignment of headcount request review tasks.
Figure 5. Headcount Request Workflow initiation form




The user who starts the workflow can choose whether to modify the default
settings, and then clicks OK to start the workflow. The Headcount Requests
document library now shows the Headcount Request Workflow status as In Progress
on the headcount request.
Figure 6. Headcount Request Workflow in progress
Clicking the In Progress link for the workflow displays the Workflow Status page
(Figure 7). This page shows the currently assigned tasks and workflow history.
Figure 7. Headcount Request Workflow Status page




The status page also shows that the workflow has sent an e-mail message to the
person specified in the Reports To field on the Headcount Request form, and the
person who initiated the workflow (in this case, the person is the same), to let both
know that the workflow has started. The Workflow Started e-mail message, shown
in Figure 8, contains headcount request information pulled from the form and a link
to the Workflow Status page.
Figure 8. Workflow Started e-mail message




Completing Headcount Request Workflow Tasks
In addition to sending workflow started e-mail messages, the workflow has
assigned tasks to the senior leadership team members specified on the workflow
initiation form, and has sent them a notification e-mail message that lets them
know they have a headcount request to review. The task notification e-mail
message contains headcount request information pulled from the form, the senior
leadership team instructions specified on the workflow initiation form, and a link to
a form that the reviewer can use to approve or deny the request.
Figure 9. Workflow Approval task notification e-mail message
The approver clicks the link in the e-mail message. A custom workflow task edit
form opens in which the approver can approve or deny the request. Clicking
either Approve or Deny(see Figure 10) marks the task as completed.
Figure 10. Headcount Request Review task edit form
The workflow tracks the number of approved and denied headcount request
approval tasks. If all approval tasks are completed and the required number of
approvals has not been reached, the workflow sends an e-mail message to the
person specified in the request form's Reports To field and to the workflow
initiator. This message lets them know that the headcount request was denied. As
soon as the required number of approvals is reached, the workflow moves to the
next stage. In this stage, tasks are assigned to the specified operations team
members so that they know to open a position for the headcount request. Figure 11
shows the Workflow Status page when the required number of approvals is
reached.
Figure 11. Headcount Request Workflow approved status
As shown in Figure 12, the e-mail message that is sent to the specified operations
team members contains headcount request information pulled from the request
form, the operations team instructions from the workflow initiation form, and a link
to a form that the team member can use to save the position number.
Figure 12. Workflow Position Number task notification e-mail message
The operations team member opens the position, generates a position number, and
then clicks the link in the e-mail message. A headcount request position form opens
in which the operations team member can add the position number to the original
headcount request. The team member then clicks Save.
Figure 13. Headcount Request Position Number task edit form
The workflow saves the position number to the original Headcount Request form, as
shown in Figure 14.
Figure 14. Headcount Request Workflow completed status
The workflow then sends a workflow completed e-mail message to the person
specified in the request form's Reports To field and to the workflow initiator, to
inform them that the headcount request is completed and whether the request was
approved. Then, the workflow ends.
Figure 15. Workflow Completed e-mail message
Solution Implementation Details
The Headcount Request Approval solution was created with Visual Studio 2008. The
following sections provide details about the implementation of the solution's
components.
Headcount Request InfoPath Form
The headcount request InfoPath form that is used to submit new headcount
requests is a browser-enabled form template that allows InfoPath Forms Services to
host it. Hosting the form in the browser removes the requirement that users have
the InfoPath client installed, and simplifies the deployment and update processes.
The Headcount Request form has two views:
      A primary view that users interact with when submitting headcount requests
      A debugging view that can be used to view debug messages generated by
       the form code during processing
The Headcount Request form uses managed code to generate a unique form name
when saving a form to the Headcount Requests document library. It handles the
form's Loading event and determines the location to save the file to, based on
whether a new or existing form is being loaded. The location to save to is stored in
the FormState dictionary for later use.
C#
private object _strSaveLocation
{
      get { return FormState["_strSaveLocation"]; }
      set { FormState["_strSaveLocation"] = value; }
}


public void FormEvents_Loading(object sender, LoadingEventArgs e)
{
      ClearDebugMessages();


      // See if the form was opened in the browser. If so, and it is a
new
      // form, we get the location to save to from the
      // "SaveLocation" parameter. Else, we get it from the
      // "Source" parameter. If the form was opened in the client, we
      // get the Uri from the form template.


      if (Application.Environment.IsBrowser)
      {
          try
          {
                // If this is a new form, the input parameters will
contain
                // the SaveLocation parameter value. If not, this will
                // throw an exception that means this is an existing form.
                _strSaveLocation =
                   e.InputParameters["SaveLocation"].ToString();
                WriteDebugMsg("This is a new form. SaveLocation = " +
                    _strSaveLocation);
            }
            catch
            {
                // This is an existing form. Get the save location from
the
                // base part of the Source parameter value.
                string strSource = e.InputParameters["Source"].ToString();
                _strSaveLocation =
                    strSource.Substring(0, strSource.IndexOf("Forms") -
1);
            }
      }
      else
            _strSaveLocation = this.Template.Uri.ToString();
}
The Click event for the Save button and Close button is handled to perform the
saving of the form. The code in the click handler determines if a new or existing
form is being saved, and generates a unique file name if needed. It then uses of the
form's Submit to Document Library data connection to save the form.
C#
public void btnSaveAndClose_Clicked(object sender, ClickedEventArgs e)
{
      try
      {
            // Check whether this is an existing form by checking the
            // form's Uri property to determine if it is equal to "New
Form".
            // If it is, this is a new form instance being saved for the
            // first time. Else, it's an existing form in a SharePoint
list
            // that is being saved again.


            string infoPathFileName = string.Empty;
       if (this.Uri == "New Form")
       {
            // This is a new form; generate a file name by
concatenating
             // the Position and Team fields with the current
date/time.


             XPathNavigator xpathNavigator = this.CreateNavigator();
             string teamPart =
                xpathNavigator.SelectSingleNode(
                     "/my:HeadcountRequestFields/my:Team",
                     this.NamespaceManager).Value;


             string dateTimePart = FormatDateTime(DateTime.Now);


             infoPathFileName = teamPart + dateTimePart;
             infoPathFileName = infoPathFileName.Replace(" ", "");


             WriteDebugMsg("This is a new form named " +
                infoPathFileName);
       }
       else
       {
             // This is an existing form; reuse the form's name.
             string url = this.Uri;
             int startIndex = url.LastIndexOf("/") + 1;
             int length = url.Length - startIndex;


             infoPathFileName =
                System.Uri.EscapeDataString(
                     url.Substring(startIndex, length));


             WriteDebugMsg("This is an existing form named " +
                   infoPathFileName);
         }


         if (infoPathFileName != string.Empty)
         {
              // Use the "Submit to Document Library" data connection
              // to save the form.
              FileSubmitConnection fileSubmitConnection =
               (FileSubmitConnection)(this.DataConnections["Submit to
Document Library"]);


              WriteDebugMsg("Save Location: " + _strSaveLocation);


              fileSubmitConnection.FolderUrl =
                   _strSaveLocation.ToString();
              fileSubmitConnection.Filename.SetStringValue(
                   infoPathFileName);
              fileSubmitConnection.Execute();


              WriteDebugMsg("Form submitted to " +
                   fileSubmitConnection.FolderUrl);
         }
    }
    catch (Exception ex)
    {
         WriteDebugMsg(ex.Message);
    }
}
The following table lists key Headcount Request form template files and folders.
Table 1. Key Headcount Request form template files and folders
File                       Description

HeadcountRequestIPForm Sample code folder that contains the project file and
                       source code for the Headcount Request form.
HeadcountRequisition.xsn Published InfoPath Headcount Request form template,
                         located in the
                         HeadcountRequest\HeadcountRequestIPForm\Published
                         sample folder.
FormCode.cs                Managed code file for the Headcount Request form
                           template.
Headcount Request Workflow Association Form and Initiation Form
The Headcount Request Workflow association form and initiation form allow users
to specify the workflow settings when associating the workflow with the Headcount
Requests document library, and when starting the workflow on a Headcount
Request form.
The workflow association form and initiation form are implemented as ASP.NET
.aspx pages in a class library named HeadcountRequestAspxPages.dll. The
association form and initiation form classes derive from the same base
class, HeadcountRequestWFDataPages, which is derived from
the Microsoft.SharePoint.WebControls.LayoutsPageBase class.
TheHeadcountRequestWFDataPages base class implements methods for
serializing form data to and from an XML string.
The following table lists key Headcount Request Workflow association form and
initiation form files and folders.
Table 2. Key Headcount Request Workflow association form and initiation
form files and folders
File                                Description

HeadcountRequestAspxPages           Sample code folder that contains the project
                                    file and source code for the Headcount
                                    Request Workflow association form and
                                    initiation form.
HeadcountRequestWFAssoc.aspx        Workflow association form.
HeadcountRequestWFAssoc.cs          Workflow association form code-behind file.
HeadcountRequestWFInit.aspx         Workflow initiation form.
HeadcountRequestWFInit.cs           Workflow initiation form code-behind file.
HeadcountRequestWFDataPages.cs Code file for
                               the HeadcountRequestWFDataPages base
                               class that the association form and initiation
                                      form classes derive from.
FormData.cs                           Code file for the FormData class, which is
                                      used when serializing data to and from the
                                      workflow forms.
Headcount Request Workflow
The Headcount Request Workflow is a SharePoint sequential workflow that is
responsible for assigning tasks and sending notification e-mail messages to
workflow participants.
The workflow has two phases:
      The reviewer phase, during which senior leadership team members are
       assigned review tasks
      The position number phase, during which operations team members are
       assigned tasks
Figure 16 shows the reviewer phase.
Figure 16. Workflow reviewer phase
The reviewer phase of the workflow uses a replicator activity to create and assign
headcount request review tasks to senior leadership team members. The replicator
is initialized with the names of each of the senior leadership team members. The
list of reviewers is generated in the OnWorkflowActivated.Invoked method by
deserializing the data from the workflow initiation form into a FormData object.
C#
private void onWorkflowActivated_MethodInvoking(object sender,
    ExternalDataEventArgs e)
{
    workflowId = workflowProperties.WorkflowId;


    // Helper defined in FormData.cs
    FormData data =
         Helper.DeserializeFormData(workflowProperties.InitiationData);


    this.reviewers = data.GetReviewers();
    this.opsTeamMembers = data.GetOpsTeamMembers();
    serialExecution = data.CreateTasksInSerial;
    reviewerDescription = data.Description;
    opsTeamDescription = data.OpsTeamDescription;
    requiredApprovalCount = data.RequiredApprovalCount;


    historyDescription = "Workflow started.";
}
Then, the list of reviewers is used to initialize the InitialChildData property of the
replicator activity.
C#
private void OnApproverTaskReplicatorInitialized(object sender,
    EventArgs e)
{
    approverTaskReplicator.InitialChildData = reviewers;


    if (serialExecution)
         approverTaskReplicator.ExecutionType = ExecutionType.Sequence;
     else
         approverTaskReplicator.ExecutionType = ExecutionType.Parallel;
}
The reviewer phase uses an OnTaskCreated activity as part of the replicator
sequence to send a notification e-mail to each reviewer. It then waits for the task to
complete, which happens when a reviewer approves or denies the request. The
replicator uses a code condition for its UntilCondition property to determine when
it should end. TheapprovalPhaseFinished method checks whether the required
number of approvals has been reached or if all reviewers have completed their
tasks. It returns true if the replicator should end, or false if it should continue.
C#
private void approvalPhaseFinished(object sender,
     ConditionalEventArgs e)
{
     if(currentApprovalCount + currentDenialCount == reviewers.Length
||
         currentApprovalCount >= requiredApprovalCount)
         e.Result = true;
     else
         e.Result = false;
}
The workflow uses a code activity to send an e-mail message to the person
specified in the Reports To field on the headcount request and to the person
initiating the workflow, to let them know that the request is being processed. A
code activity is used rather than a SendEmail activity because of the desire to
generate a custom e-mail message that includes headcount request details from
the original request form. The same e-mail generation code is used to create the
task notification e-mail messages, and makes use of
theHeadcountRequestFields class to get the contents of the original Office
InfoPath Headcount Request form. The XML Schema Definition Tool (xsd.exe) was
used to generate theHeadcountRequestFields class, by running the tool against
the Headcount Request form schema.
The position number phase of the workflow also uses a replicator to assign tasks
and send e-mail messages to the specified members of the operations team. Figure
17 shows the position number phase.
Figure 17. Workflow position number phase
The position number phase first checks whether the required number of approvals
has been reached and, if so, uses a replicator to assign tasks. The replicator
sequence uses aCreateTaskWithContentType activity to create the tasks so that
the custom task edit form for operations team members will be displayed when
members edit their assigned task. For more information about the content types
used by the Headcount Request Workflow, see Headcount Request SharePoint
Content Types. As soon as a position number task is complete the replicator ends,
allowing the workflow to end after sending workflow completed e-mail messages to
the workflow originator and the contact specified as the Reports To person on the
Headcount Request form.
The following table lists key Headcount Request Workflow files and folders.
Table 3. Key Headcount Request Workflow files and folders
File                                Description

HeadcountRequestWorkflow            Sample code folder that contains the project
                                    file and source code for the Headcount Request
                                    Workflow.
Workflow1.cs                        Primary code file for the workflow; contains
                                    the core workflow functionality.
FormData.cs                         Code file for the FormData class, which is
                                    used when serializing data to and from the
                                    workflow forms.
HeadcountRequestIPFormFields.cs Code file for
                                the HeadcountRequestFields class, which is
                                used to access to the contents of the Office
                                InfoPath Headcount Request form.
Feature.xml

Workflow.xml
Headcount Request SharePoint Content Types
The Headcount Request Workflow uses two custom SharePoint content types to
support custom workflow task editing forms: the Leadership Team Task Workflow
content type, and the Operation Team Task Workflow content type. The custom
editing forms for the content types are implemented as ASP.NET .aspx pages, and
provide the ability for headcount request reviewers to approve or deny requests,
and for operations team members to save the position number for an approved
headcount request.
Leadership Team Task Workflow Content Type
The leadership team task workflow content type is the default task list content type
for the Headcount Request Workflow. The following XML fragment from the
workflow's workflow.xml file shows the TaskListContentTypeId attribute being
set to the unique identifier of the leadership team task workflow content type.
Xml
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Workflow
      Name="Headcount Request"
    Description="This workflow faciliates the headcount request
process."
      Id="5F837DB9-D8DB-4fae-99B2-4F90197A64FA"
      CodeBesideClass="HeadcountRequestWorkflow.HeadcountRequest"
    CodeBesideAssembly="HeadcountRequestWorkflow, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=8d9307eae9226f19"
  TaskListContentTypeId="0x01080100B33A350590D5455d81349D3111832B46"
...
The following XML is from the LeadershipTeamTaskWFCT.xml file used to define the
leadership team task workflow content type.
Xml
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <ContentType      ID="0x01080100B33A350590D5455d81349D3111832B46"
      Name="LeadershipTeamTaskWorkFlowContentType"
      Group="Headcount Request Workflow"
    Description="Create a Custom Workflow Task for the Senior
Leadership team."
      Version="0"
      Hidden="TRUE">


      <FieldRefs>
       <FieldRef ID="{83A82827-EC2D-46ce-A6CF-A68D6849B725}"
         Name="HeadcountRequestReviewerComments"
         DisplayName="Headcount Request Reviewer Comments"/>
       <FieldRef ID="{732AB06C-DE4B-4c70-88CF-7934C4AAF0DE}"
       Name="HeadcountRequestApproved"
       DisplayName="Headcount Request Approved"/>
      </FieldRefs>


      <XmlDocuments>
        <XmlDocument
NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/f
orms/url">
        <FormUrls
xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/ur
l">
             <Edit>_layouts/LeadershipTeamTaskWFCT.aspx</Edit>
           </FormUrls>
        </XmlDocument>
       </XmlDocuments>
  </ContentType>


  <Field ID="{83A82827-EC2D-46ce-A6CF-A68D6849B725}"
       Name="HeadcountRequestReviewerComments"
       SourceID="http://schemas.microsoft.com/sharepoint/v3"
       StaticName="HeadcountRequestReviewerComments"
       Group="Headcount Request Workflow"
       Type="Note"
       DisplayName="Headcount Request Reviewer Comments">
  </Field>


  <Field ID="{732AB06C-DE4B-4c70-88CF-7934C4AAF0DE}"
       Name="HeadcountRequestApproved"
       SourceID="http://schemas.microsoft.com/sharepoint/v3"
       StaticName="HeadcountRequestApproved"
       Group="Headcount Request Workflow"
       Type="Text"
       DisplayName="Headcount Request Approved">
  </Field>
</Elements>
The markup in the LeadershipTeamTaskWFCT.xml file specifies the following about
the leadership team task workflow content type:
       It inherits from the SharePoint workflow task content type by specifying
        0x010801 for the base part of its content type identifier.
       Xml
       <ContentType     ID="0x01080100B33A350590D5455d81349D3111832B46"
      It specifies that the LeadershipTeamTaskWFCT.aspx file, located in
       the _layouts folder, provides the content type's edit form.

       Xml
       <FormUrls
       xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/for
       ms/url">
         <Edit>_layouts/LeadershipTeamTaskWFCT.aspx</Edit>
       </FormUrls>
      It references two columns, also defined in the LeadershipTeamTaskWFCT.xml
       file: one for storing comments from reviewers, and one for storing whether
       the request was approved.

       Xml
          <FieldRefs>
            <FieldRef ID="{83A82827-EC2D-46ce-A6CF-A68D6849B725}"
               Name="HeadcountRequestReviewerComments"
               DisplayName="Headcount Request Reviewer Comments"/>
            <FieldRef ID="{732AB06C-DE4B-4c70-88CF-7934C4AAF0DE}"
               Name="HeadcountRequestApproved"
               DisplayName="Headcount Request Approved"/>
          </FieldRefs>
Operations Team Task Workflow Content Type
The operations team task workflow content type is referenced when the position
number phase of the Headcount Request Workflow creates tasks for the operations
team members with the CreateTaskWithContentType activity. This allows the
custom task edit form to be displayed. The operations team task workflow content
type identifier is specified for the value of the ContentTypeId property of
the CreateTaskWithContentType activity, as shown in Figure 18.
Figure 18. CreateTaskWithContentType activity ContentTypeId property
The following XML is from the OpsTeamTaskWFCT.xml file used to define the
operations team task workflow content type.
Xml
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <ContentType    ID="0x010801006439AECCDEAE4db2A422A3A04C79CC83"
    Name="OpsTeamTaskWorkFlowContentType"
    Group="Headcount Request Workflow"
    Description="Create a Custom Workflow Task for the Operations
team."
    Version="0"
    Hidden="TRUE">


    <FieldRefs>
      <FieldRef ID="{7B37146C-B563-411b-B004-9740C8E2C272}"
         Name="HeadcountRequestOpsComments"
         DisplayName="Headcount Request Ops Comments"/>
      <FieldRef ID="{10414189-35AD-40b3-AF50-740ACAD91246}"
         Name="HeadcountRequestPositionNumber"
         DisplayName="Headcount Request Position Number"/>
    </FieldRefs>


    <XmlDocuments>
      <XmlDocument
NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/f
orms/url">
           <FormUrls
xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms/ur
l">
             <Edit>_layouts/OpsTeamTaskWFCT.aspx</Edit>
           </FormUrls>
        </XmlDocument>
       </XmlDocuments>
  </ContentType>


  <Field ID="{7B37146C-B563-411b-B004-9740C8E2C272}"
       Name="HeadcountRequestOpsComments"
       SourceID="http://schemas.microsoft.com/sharepoint/v3"
       StaticName="HeadcountRequestOpsComments"
       Group="Headcount Request Workflow"
       Type="Note"
       DisplayName="Headcount Request Ops Team Member Comments">
  </Field>


  <Field ID="{10414189-35AD-40b3-AF50-740ACAD91246}"
       Name="HeadcountRequestPositionNumber"
       SourceID="http://schemas.microsoft.com/sharepoint/v3"
       StaticName="HeadcountRequestPositionNumber"
       Group="Headcount Request Workflow"
       Type="Text"
       DisplayName="Headcount Request Position Number">
  </Field>
</Elements>
The markup in the OpsTeamTaskWFCT.xml file specifies the following about the
operations team task workflow content type:
       It inherits from the SharePoint workflow task content type by specifying
        0x010801 for the base part of its content type identifier.
       Xml
       <ContentType     ID="0x010801006439AECCDEAE4db2A422A3A04C79CC83"
       For more information on the SharePoint base content type hierarchy,
       see Base Content Type Hierarchy.
      It specifies that the OpsTeamTaskWFCT.aspx file, located in the _layouts
       folder, provides the content type's edit form.

       Xml
       <FormUrls
       xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/for
       ms/url">
         <Edit>_layouts/OpsTeamTaskWFCT.aspx</Edit>
       </FormUrls>
      It references two columns, also defined in the OpsTeamTaskWFCT.xml file:
       one for storing comments from operations team members, and one for
       storing the request's position number.

       Xml
          <FieldRefs>
             <FieldRef ID="{7B37146C-B563-411b-B004-9740C8E2C272}"
               Name="HeadcountRequestOpsComments"
               DisplayName="Headcount Request Ops Comments"/>
             <FieldRef ID="{10414189-35AD-40b3-AF50-740ACAD91246}"
               Name="HeadcountRequestPositionNumber"
               DisplayName="Headcount Request Position Number"/>
       </FieldRefs>
The following table lists key Headcount Request Workflow content type files and
folders.
Table 4. Key Headcount Request Workflow content type files and folders
File                              Description

LeadershipTeamTaskWFCT            Sample code folder containing the project file
                                  and source code for the Headcount Request
                                  leadership team task workflow content type.
OpsTeamTaskWFCT                   Sample code folder containing the project file
                                  and source code for the Headcount Request
                                  operations team task workflow content type.
LeadershipTeamTaskWFCT.aspx Leadership team task workflow content type edit
                                  form.
LeadershipTeamTaskWFCT.cs         Code file for the leadership team task workflow
                                  content type edit form.
OpsTeamTaskWFCT.aspx              Operations team task workflow content type edit
                                  form.
OpsTeamTaskWFCT.cs                Code file for the operations team task workflow
                                  content type edit form.
LeadershipTeamTaskWFCT.xml        XML file that contains the definition of the
                                  leadership team task workflow content type.
OpsTeamTaskWFCT.xml               XML file that contains the definition of the
                                  operations team task workflow content type.

Headcount Request Workflow Solution Deployment
The following sections provide information related to deploying the components that
make up the Headcount Request Workflow solution.
Headcount Request InfoPath Form Template
Because the Headcount Request InfoPath form template uses managed code, an
administrator must deploy it to InfoPath Forms Services. Deploying a browser-
enabled form template that requires administrator approval for use with InfoPath
Forms Services is a three-step process:
   1. Verify the form template.
   2. Upload the template.
   3. Activate the template.
To upload and activate the Headcount Request form template
   1. Navigate to the SharePoint Central Administration site, and then click
      the Application Management tab.
   2. On the Application Management page, click the Upload form template link
      in the InfoPath Forms Services section.
   3. Browse to the HeadcountRequestIPForm\Published folder under the top-
      level (root) Headcount Request sample folder, and then double-click
      the HeadcountRequisition.xsn file. This is a published version of the
      Headcount Request form template.
   4. Click the Upload button to upload the form template.
   5. After the form template is uploaded and its Status on the Manage Form
      Templates page shows Ready, pause the cursor over the template name,
      and then click the down arrow to display the drop-down menu.
      Click Activate to a Site Collection.
   6. On the Activate Form Template page, select the site collection you want, and
      then click OK.
For more information about deploying administrator-approved form templates,
see Deploy Administrator-Approved Form Templates (Office SharePoint Server) on
Microsoft TechNet.
Headcount Request Workflow
The Headcount Request Workflow with its associated forms and content types can
be deployed by using one of three batch files located in the top-level folder of the
Headcount Request sample. The three batch files are:
      InstallAll.bat Installs all workflow-related assemblies to the global assembly
       cache; copies workflow association, initiation, and task edit forms to the
       SharePoint _layouts folder; and copies workflow and content type feature
       files to the SharePoint Features folder and installs and activates them.
      QuickPagesUpdate.bat Copies workflow association, initiation, and task
       edit forms to the SharePoint _layouts folder.
      QuickUpdate.bat Installs all workflow-related assemblies to the global
       assembly cache; and copies workflow association, initiation and task edit
       forms to the SharePoint _layouts folder.
To deploy the Headcount Request Workflow, open a Command Prompt window,
navigate to the top-level folder of the Headcount Request sample, and execute the
batch file you want. If you are deploying the workflow for the first time, run the
InstallAll.bat file. You can use the QuickPagesUpdate.bat and QuickUpdate.bat files
if the sample code is modified and the workflow features are already installed and
activated.
Headcount Requests Document Library
A list template for the Headcount Requests document library is provided in the
HeadcountRequestDocLibrary folder under the top-level sample folder. You can use
the list template to easily create a document library that uses the Headcount
Request form as its document template.
To add the Headcount Requests document library list template to the
SharePoint list template gallery
   1. On the Site Actions menu, click Site Settings, and then click Modify All
      Site Settings.
   2. On the Site Settings page, click the List Templates link in
      the Galleries section.
   3. On the List Template Gallery page, click Upload to display the Upload
      Template: List Template Gallery page.
   4. Browse to the HeadcountRequestDocLibrary folder under the root Headcount
      Request sample folder, and then double-click the
      HeadcountRequestDocumentLibrary.stp file.
   5. Click OK on the Upload Template: List Template Gallery page to upload the
      template.
   6. On the List Template Gallery: HeadcountRequestDocumentLibrary page, you
      can modify template settings if you choose. Click OK to save the changes to
      the gallery.
Now that the list template is added, you can create an instance of the Headcount
Requests document library.
To create an instance of the Headcount Requests document library
   1. On the Site Actions menu, click Site Settings, and then click Modify All
      Site Settings.
   2. On the Site Settings page, click the Site libraries and lists link in the Site
      Administration section.
   3. On the Site Libraries and Lists page, click the Create new content link.
   4. On the Create page, click the Headcount Request Document Library link
      in the Libraries section.
   5. On the New page, type a name and description for the document library, and
      then click the Create button.
The next step is to associate the Headcount Request workflow with the document
library.
To associate the workflow with the document library
   1. Navigate to the Headcount Request document library you created previously.
   2. Click Settings, and then click Document Library Settings.
   3. On the Customize page for the document library, click the Workflow
      settings link in the Permissions and Management section.
   4. On the Add a Workflow page, select the Headcount Request workflow
      template, name the workflow, and select the workflow task and history lists.
      To be able to use the workflow initiation form to override the workflow
      settings specified at association time, leave the option to allow the workflow
      to be manually started.
   5. Click Next to display the Headcount Request Workflow association form.
   6. Specify the default settings for the workflow. Use the contact selector to
      specify the senior leadership team members to act as reviewers and the
      operations team members. Type messages to include with the requests, and
      specify the minimum number of required approvals.
   7. Click OK to save the workflow association.
The final step to create the Headcount Requests document library is to set its
document template. The list template for the document library sets the document
template for the Form content type to point to
http://moss.litwareinc.com/FormServerTemplates/HeadcountRequisition.xsn. You
must change this to point to the correct location of the Headcount Request form
template.
To determine the location of the form template and set the document
template to point to it
   1. On the Site Actions menu, click View All Site Content. The All Site
      Content page will be displayed.
   2. On the All Site Content page, click the Form Templates link in
      the Document Libraries section to display the list of form templates that
      are activated to the site collection. If the Headcount Request form was
      previously uploaded and activated, the HeadcountRequisition form should be
      listed.
   3. Right-click the HeadcountRequisition link, and then click Copy Shortcut.
   4. Navigate back to the Headcount Requests document library created
      previously, click Settings, and then click Document Library Settings.
   5. On the document library's Customize page, click the Form content type in
      the Content Types section.
   6. On the List Content Type: Form page, click , the Advanced settings link.
   7. Select the existing document template URL and replace it by pasting the form
      template shortcut copied in step 3.
   8. Click OK to save the change.
Now the document library is correctly configured. New headcount requests can be
submitted with the Headcount Request form, and workflows can be run against
forms in the document library.

  Note:

SharePoint e-mail settings must be correctly configured to enable the Headcount
Request workflow to successfully send e-mail notifications. For more information
about configuring SharePoint e-mail settings, see Configure Outgoing E-Mail
Settings (Office SharePoint Server).

Conclusion
The Headcount Request Approval solution presented in this article demonstrates
using Visual Studio 2008 to create a SharePoint sequential workflow to facilitate a
simple headcount request approval process. The solution uses an Office InfoPath
2007 browser-compatible form to allow users to submit headcount requests to a
SharePoint document library. A SharePoint sequential workflow is provided, which
uses ASP.NET .aspx pages for the workflow association forms and initiation forms.
In addition, the workflow uses two custom content types to enable the use of
custom workflow task editing forms
Developing SharePoint 2007 Sequential and
State Machine Workflows with Visual Studio
2008
Summary: Learn how to develop sequential workflows and state machine
workflows for Microsoft Office SharePoint Server 2007 by using Microsoft Visual
Studio 2008. (23 printed pages)
Applies to: Microsoft Office SharePoint Server 2007, Microsoft Visual Studio 2008
Contents
      Introduction to SharePoint Workflows
      Windows Workflow Foundation Overview
      Developing SharePoint Workflows Using Visual Studio
      Developing a Sequential Workflow
      Developing a State Machine Workflow
      Deploying a Workflow
      Conclusion
      About the Author
      Additional Resources

Introduction to SharePoint Workflows
Over the past decade, many companies have invested in IT solutions that formalize
work processes or workflows. A workflow is the sequence of events required to
achieve a desired result; a workflow is the means to an end. By formalizing
workflows, companies seek to repeat their success. That is, they learn which
activities tend to produce a successful result and then build a process that helps
ensure the same result.
Microsoft Office SharePoint Server 2007 is increasingly serving as the central
nervous system of many companies. Traditionally, Office SharePoint Server has
been used as a portal server for corporate intranets. However, as the capabilities of
Office SharePoint Server have expanded in breadth and depth, Office SharePoint
Server is different things to different people depending on how they are using it.
One of the core competencies of Office SharePoint Server is enabling collaboration.
The combination of collaboration features with document management features
makes Office SharePoint Server a compelling platform for many corporate workflow
processes. Recognizing this fact, Microsoft has embedded Windows Workflow
Foundation (WF) within Office SharePoint Server to enable workflows to be
formalized by using Office SharePoint Server.
Office SharePoint Server 2007 contains several built-in workflow templates that
address commonly encountered workflow situations. However, other than the most
trivial workflows, workflow processes are a lot like snowflakes—no two ever seem
to be alike. When it comes to designing custom workflows, there are two Microsoft
tools to choose from: Microsoft Office SharePoint Designer 2007 and Microsoft
Visual Studio.
The objective of this article is to provide an overview of how to develop a custom
SharePoint workflow by using Microsoft Visual Studio 2008. Before discussing
workflow development with Visual Studio, however, it is essential to have a solid
understanding of basic workflow terms and methodology.

Windows Workflow Foundation Overview
Office SharePoint Server uses WF to provide workflow capability. WF consists of an
activity library, a programming framework, a run-time workflow engine, and run-
time services, components, and tools for building workflow-enabled applications.
The run-time engine and services components run within a host's application
process.
A workflow in WF is defined by the discrete activities that compose it. When you
design a workflow in Visual Studio, you drag activities onto the workflow design
surface, and then define the relationship between the activities. Everything is an
activity. Do you want to execute a bit of code at a specific place in your workflow?
Drop a code activity in the appropriate place. Want to send an e-mail message as
part of the workflow? Drop a send e-mail activity in the appropriate place. If you
compare this process to developing a user control, you notice that the primary
difference is one of semantics: Instead of workflow activities, you drop controls or
components onto a design surface. Just as user controls have events that you can
hook into, workflow activities also have associated events that provide additional
hooks for you to use to add programming logic.
Types of Workflows
There are two types of workflows in WF: sequential workflows and state machine
workflows. A sequential workflow follows a linear set of tasks. Although sequential
workflows may include branching and looping, progress through the workflow
moves from start to finish along a predetermined path.
Whereas a sequential workflow involves a set of activities in a predefined sequence,
a state machine workflow consists of possible states that a given entity can occupy
with activities that should occur for each state. State machines define a set of
events that can be received for any given state, and when an event occurs an
action is performed. One of the activities that might occur is a transition to a new
state. By modeling a set of states instead of a sequence of events, you have much
more flexibility to implement a workflow because the workflow does not need to
follow a rigid sequence of activities.
Although a state machine uses a different paradigm at a high-level, the behavior of
individual states is implemented much like a sequential workflow. That is, within an
individual state—more specifically, within an event associated with a given state—
you use the same activities that make up a sequential workflow. After you
understand the paradigm of a state machine, implementing the states "feels" much
like developing a sequential workflow.

Developing SharePoint Workflows Using Visual Studio
Visual Studio 2008 with Visual Studio Tools for Office simplifies workflow
development by including two workflow project templates: SharePoint 2007
Sequential Workflow and SharePoint 2007 State Machine Workflow. The Sequential
Workflow template is intended for workflows that follow a predetermined set of
tasks. These workflows might involve branching or looping; however, they involve
following a sequential flow or progress through the activities that make up the
workflow. A simple document review process is a good example of a sequential
workflow.
The State Machine Workflow template is intended for workflows that move between
states and never follow a specific sequence of activities. For example, consider a
workflow that concerns bug resolution. You can think of a bug's status at any given
time as its state. During its lifetime, a bug's status can iterate through several
states. While it is possible that some bugs are resolved in a sequential manner,
there are other occasions where the resolution is much more random, if there is a
resolution at all. For workflows such as these, consider using the state machine
model.
Glancing ahead in this article, you might be overwhelmed by the number of steps
each workflow procedure includes. Don't worry; the steps are easy and there is
much repetition. A significant amount of workflow work is "mouse" work, that is,
you complete activities through simple mouse clicks and keyboard entry, such as
arranging items on a design surface and then configuring object properties.

Developing a Sequential Workflow
Conceptually, sequential workflows are easier to understand than state machine
workflows. The following steps walk you through the tasks involved in building a
sequential workflow—in this case, a simple document review workflow. This
document review workflow watches for new items in a document library, and begins
automatically when a new item is added to the document library. When the
workflow is initiated, it automatically creates a technical edit task in a task list that
is associated with the workflow. After the technical edit is complete, the workflow
creates an editorial review task in the task list. When the editorial review is
complete, the workflow terminates.
Creating the Initial Project
The following steps show how to create the workflow project and set the workflow's
general attributes. The attributes you set include the SharePoint site and the
document library that the workflow will be associated with, and how a new
workflow starts.
To create the initial project
   1. Open Visual Studio and create a new project.
2. Select the Office project type node, and then click the SharePoint 2007
   Sequential Workflow template.
3. Name the project SimpleSequentialDocumentReview, and then click OK.
4. In the first New Office SharePoint Workflow dialog box, provide a user-
   friendly name for the workflow (for example, Simple Document Review), and
   then provide a valid SharePoint site URL to use for debugging the workflow.

   Figure 1. Name the workflow and specify a SharePoint site to use for
   debugging




5. In the second New Office SharePoint Workflow dialog box, select the
   library, history list, and task list that Visual Studio will associate with your
   workflow when debugging.
   Figure 2. Choose lists or libraries to use for workflow association,
   history, and tasks




6. In the final New Office SharePoint Workflow dialog box, accept the
   default settings, and then click Finish.
Figure 3. Indicate how the workflow can be started




If you make a mistake or change your mind about the initial settings, you
can access the initial workflow dialog boxes to make changes at any time by
selecting the project inSolution Explorer, and then clicking the ellipsis in
the TargetSite property (some of the other properties also exhibit this
behavior).
      Figure 4. Initial view of a sequential workflow project




Visually Designing the Workflow
To design a workflow, drag activities from the SharePoint
Workflow and Windows Workflow v3.0 tabs in the Toolbox to the designer
work surface. For the simple document workflow, you will use a
couple CreateTask activities, a couple OnTaskChanged activities, and a
couple While activities. To lay out the simple sequential document review
workflow, perform the following steps.
To design a workflow
   1. In the Toolbox, do the following:
         a. Drag a CreateTask activity from the SharePoint Workflow tab onto
            the design surface directly under
            the OnWorkflowActivated1 activity.
      b. Drag a While activity from the Windows Workflow v3.0 tab onto
         the design surface, under the CreateTask1 activity.
      c. Drag an OnTaskChanged activity to within WhileActivity1, on top of
         the text that reads Drop an Activity Here.
      d. Drag another CreateTask activity to under (not inside
         of) WhileActivity1.
      e. Drag another While activity to under CreateTask2.
      f. Drag another OnTaskChanged activity into WhileActivity2.

         Figure 5. Simple sequential workflow after laying out workflow




         activities


2. Set the properties that are associated with CreateTask1, as follows:
      a. Select the CreateTask1 activity, and rename
         it CreateTechReviewTask.
      b. Create a task correlation token by entering TechReviewToken in
         the CorrelationToken property; a PLUS SIGN (+) appears next to
         the CorrelationToken property. Click the PLUS SIGN to view
         the OwnerActivityName property and set this property
         to Workflow1.

           Note:

          Correlation tokens are explained after this sequence of instructions.
      c. Click the ellipsis in the TaskId property.
      d. On the Bind to a new member tab, click Create Field, and then
         click OK. (Note the name of the new field.)
      e. Click the ellipsis in the TaskProperties property.
      f. On the Bind to a new member tab, click Create Field, and then
         click OK. (Note the name of the new field.)
3. Set the properties that are associated with CreateTask2 by repeating steps
   2a–e, with the following exceptions:
      a. Rename CreateTask2 to CreateEditorialReviewTask.
      b. Create a correlation token named EditorialReviewToken in
         the CorrelationToken property.
      c. Set the OwnerActivityName property to Workflow1.
4. Set the properties that are associated with OnTaskChanged1, as follows:
      a. Select OnTaskChanged1, and then rename
         it OnTechReviewTaskChanged.
      b. Set the CorrelationToken property to TechReviewToken.
      c. Bind the AfterProperties property field to a new field (similar to steps
         2e–f).
5. Set the properties associated with onTaskChanged2.
      a. Select OnTaskChanged2, and then rename
         it OnEditorialReviewTaskChanged.
      b. Set the CorrelationToken property to EditorialReviewToken.
      c. Bind the AfterProperties property field to a new field (similar to steps
         2e–f).
Correlation tokens are an important concept associated with developing workflows.
Correlation tokens are used to group associated, related activities in an activity.
Correlation tokens are important to understand because if you do not assign
correlation tokens correctly, your workflow might not work as you expect.
Specifically, events associated with activities might not receive event notifications.
By default, a workflow token is created as part of creating a workflow project. You
should also create a new token for each task that is created as part of a workflow.
Then, for each activity associated with a given task, set the correlation token equal
to the correlation token associated with the task.
Another important concept associated with the previous steps is that
of BeforeProperties, AfterProperties, and TaskProperties. TaskProperties is
a property of a CreateTaskactivity. BeforeProperties and AfterProperties are
properties used by an OnTaskChanged activity. All of these items
areMicrosoft.SharePoint.Workflow.SPWorkflowTaskProperties objects.
An SPWorkflowTaskProperties object contains properties and methods that
enable you to affect the fields associated with a given task item. For example, by
using an SPWorkflowTaskProperties object, you can assign the task to
someone, set the due date, or determine the percent
complete. BeforeProperties, AfterProperties, and TaskProperties are all point-
in-time objects. That is, the values do not change as the task changes. For
an OnTaskChangedactivity, BeforeProperties represent the state of a task item
before changes were made; AfterProperties represent the state of the task item
after the changes were made. For aCreateTask activity, TaskProperties provides
you with a way to set the initial properties of the task item when it is created. This
is demonstrated later in this article.
Creating Task Items
Although you can set some of the properties of a CreateTask activity by using the
designer, it is likely that many of the actual values used to set up the task need to
be determined programmatically. To do this, associate an event handler with
the CreateTask activity.
To associate an event handler with the CreateTask activity
   1. Select the createTechReviewTask and view the events associated with the
      activity in the Properties window.
   2. Double-click the MethodInvoking handler to generate an event handler
      stub that will respond to the MethodInvoking event that occurs before the
      activity is executed.
   3. Add the following code to the event handler to set the task identifier for the
      task, and set the due date for the following day.

      Visual Basic
      createTechReviewTask_TaskId1 = Guid.NewGuid()
      createTechReviewTask_TaskProperties1.DueDate =
      Date.Now.AddDays(1.0)
      createTechReviewTask_TaskProperties1.Title = "Perform Tech
      Review"
   4. Perform the same steps for the createEditorialReview activity, but add the
      following code to the event handler.

      Visual Basic
      createEditorialReviewTask_TaskId1 = Guid.NewGuid()
      createEditorialReviewTask_TaskProperties1.DueDate =
      Date.Now.AddDays(1.0)
      createEditorialReviewTask_TaskProperties1.Title = "Perform
      Editorial Review"
Waiting for Tasks to Complete
In task-based workflows such as the simple document review workflow discussed in
this article, While activities are used to implement the loop needed to watch for
task-changed activities, and to see whether a task was marked as complete. To use
a While activity, drag a While activity onto the design surface, and then drag any
activities that you want to execute repetitively until the While activity terminates
and drop them in the While activity.
There are two methods for terminating a While activity: using a code condition or
using a declarative rule condition. To use a code condition, add a procedure to the
project that sets a Boolean result flag to true or false. To use a declarative rule
condition, add a rule to the project. In each pass through the While activity, the
rule is evaluated to determine whether the terminating condition was met.
To show how to use both methods for terminating a While activity, we use a code
condition for the While activity that is associated with the technical review task and
a declarative rule condition for the While activity associated with the editorial
review task.
To terminate a While activity
   1. Implement the terminating condition of whileActivity1, as follows:
         a. Switch to the code view and add the following code to Workflow1.vb.

             Visual Basic
             Private bTaskNotFinished As Boolean = True


                 Private Sub TaskNotFinished(ByVal sender As
             System.Object, _
                                                  ByVal e As _

             System.Workflow.Activities.ConditionalEventArgs)
                  e.Result = bTaskNotFinished


              End Sub
      b. Switch back to the workflow designer and select
         the onTechReviewTaskChanged activity.
      c. Click the Events button in the Properties window to see the events
         that are associated with onTechReviewTaskChanged.
      d. Double-click the Invoked event to generate a handler for it.
      e. Add the following code to
         the onTechReviewTaskChanged_Invoked handler.

         Visual Basic
         If onTechReviewTaskChanged_AfterProperties1.PercentComplete
         = 1.0 Then _
                        bTaskNotFinished = False
      f. Switch back to the workflow designer, and then select
         the whileActivity1 activity.
      g. Set the Condition property to Code Condition.
      h. Click the PLUS SIGN (+) , and then set the
         subsequent Condition property to TaskNotFinished.
2. Implement the terminating condition of whileActivity2, as follows:
      a. Select the onEditorialReviewTaskChanged activity in the designer,
         and then generate an event handler for the Invoked event.
      b. Add a class-level Boolean variable
         named bEditorialTaskNotFinished to the class.

         Visual Basic
              Private bEditorialTaskNotFinished As Boolean = True
      c. Add the following code to
         the onEditorialReviewTaskChanged_Invoked event handler.

         Visual Basic
           If
         onEditorialReviewTaskChanged_AfterProperties1.PercentComple
         te = 1.0 Then _ bEditorialTaskNotFinished = False
      d. Switch back to the workflow designer, and then select
         the whileActivity2 activity.
      e. Set the Condition property to Declarative Rule Condition.
f. Expand the Condition property.
g. Click the ellipsis in the ConditionName property to open the Select
   Condition dialog box.

   Figure 6. Use the Select Condition dialog box to create
   declarative rule conditions




h. Click New, enter the condition shown in the following figure, and then
   click OK.

   Figure 7. Example of a declarative rule condition
i. Click OK in the Select Condition dialog box.




   Figure 8. Successfully created declarative rule condition
Debugging the Workflow
Debugging SharePoint workflows is a particularly satisfying experience with Visual
Studio 2008 versus previous versions, in which the debugging process was manual.
After compiling, you had to deploy the workflow manually, recycle Microsoft
Internet Information Services (IIS), attach the Visual Studio debugger to the W3WP
process, open Internet Explorer, navigate to the correct document library, and
associate the workflow with the library. With Visual Studio 2008, you simply
press F5 and Visual Studio handles all of that for you. All you need to do is trigger a
new instance of the workflow by adding an item to the list that the workflow is
associated with (assuming you set up the workflow to start automatically when new
items are added).
There is one thing to note about debugging workflows. Because you will be looking
at Internet Explorer often while debugging the workflow, it is tempting to close the
Internet Explorer window when you are finished debugging. But instead of closing
the Internet Explorer window, it is best to stop debugging from Visual Studio. When
you stop the debugging process, Visual Studio closes the Internet Explorer window
for you.

Developing a State Machine Workflow
Now that you have experienced success with a sequential workflow, let's move on
to a state machine workflow. To help show the differences between a sequential
workflow and a state machine workflow, you will build a workflow to handle the
same document publishing process discussed previously in the sequential workflow
section. However, state machine workflows require a different approach to thinking
about a problem. Instead of focusing on the flow or sequence of events, modeling
state machines requires you to think about the states an object can assume during
the process.
In the document publishing process, the object of interest is a document. For a
simple example, assume that the document can be in the following states:
      In Progress: State of the document whenever it is actively being worked on
       by the author.
      Technical Review: State of the document during the time it is being
       reviewed for technical accuracy.
      Editorial Review: State of the document during the time it is being
       reviewed from a grammatical perspective.
      Finished: State of the document after it has passed technical and editorial
       reviews.
A state machine always has an initial state and a completed state.
Creating the Initial State Machine Project
The first set of steps addresses creating the workflow project and setting the
general attributes of the workflow such as the SharePoint site and document library
it will be associated with, and how a new workflow is started.
To create the workflow project and set general attributes
   1. Open Visual Studio and create a new project.
  2. Select the Office project type node, and then select the SharePoint 2007
     State Machine Workflow template.
  3. Name the project SimpleStateMachineDocumentReview, and then
     click OK.
  4. In the first New Office SharePoint Workflow dialog box, provide a user-
     friendly name for the workflow (such as Simple Document Review), and then
     provide a valid SharePoint site URL to use for debugging the workflow.
  5. In the second New Office SharePoint Workflow dialog box, select the
     library, history list, and task list that Visual Studio will associate your
     workflow with when debugging.
  6. In the final New Office SharePoint Workflow dialog box, accept the
     default settings, and then click Finish.
If you make a mistake or change your mind about the initial settings, you can
access the initial workflow dialog boxes to make changes at any time by selecting
the project in Solution Explorer, and then clicking the ellipsis when you click in




the TargetSite property (some of the other properties also exhibit this same
behavior).
Figure 9. Initial view and settings of a state machine project

Adding States to a State Machine Workflow
The next task is to add states to the workflow. This is simply a matter of
dragging State objects from the Windows Workflow v3.0 tab in
the Toolbox onto the design surface and naming them appropriately. This is also a
good time to flag which state represents the completed state.
To add states to the workflow
   1. Select the existing state named Workflow1InitialState, and then rename
      it stateInProgress.
  2. In the Toolbox, do the following:
        a. Drag a State object to the design surface. Name the
           state stateTechReview.
        b. Drag a State object to the design surface. Name the
           state stateEditReview.
        c. Drag a State object to the design surface. Name the
           state stateComplete.
        d. Flag stateComplete as the completed state by right-clicking it, and
           then clicking Set as Completed State.

           Figure 10. States in a simple document review state machine




Adding Event-Driven Activities to State Machine Workflows
Event-driven activities are the lifeblood of a state machine workflow. An event-
driven activity is a specific event that a given state reacts to. A state can, and often
does, have multiple event-driven activities associated with it. In addition to event-




driven activities, there are events associated with state initialization and state
finalization that you can use to implement logic.
Within an event-driven activity, you build workflows that resemble sequential
workflows. You can think of a state machine as a collection of sequential workflows
where you define the relationship between the sequential workflows. You define the
relationship by using SetState activities within an event-driven activity to
transition from one state to another.
To add event-driven activities to a state machine workflow
   1. Right-click stateInProgress, and then click Add StateInitialization. Visual
      Studio adds a state initialization activity, and opens the designer for the
      activity. You can return to the state view of the workflow by
      clicking Workflow1 in the upper-left corner of the design surface.

      Figure 11. Adding activities to the state initialization activity
2. Add a CreateTask activity to stateInitializationActivity1, as follows:
      a. Drag a CreateTask activity from the SharePoint Workflow tab in
         the Toolbox, and drop it in stateInitializationActivity1. Name the
         task CreateInProgressTask.
      b. Create a correlation token by entering InProgressToken in
         the CorrelationToken property for CreateInProgressTask.
      c. Expand the CorrelationToken property, and
         set OwnerActivityName to stateInProgress.
      d. Click the ellipsis in the TaskId property.
      e. On the Bind to a new member tab, click Create Field, and then
         click OK.
      f. Click the ellipsis in the TaskProperties property.
      g. On the Bind to a new member tab, click Create Field, and then
         click OK.
      h. View the events associated with CreateInProgressTask, and then
         double-click in the MethodInvoking event to generate an event
         handler.
      i. Add the following code to this event handler.

         Visual Basic
         CreateInProgressTask_TaskId1 = Guid.NewGuid()
         CreateInProgressTask_TaskProperties1.Title = "Finish
         document changes/updates"
         CreateInProgressTask_TaskProperties1.DueDate =
         Date.Now.AddDays(1.0)
3. Add an event-driven activity to stateInProgress to determine when to
   transition to a new state, as follows:
      a. Switch to the design view of the workflow.
      b. Go back to the state view of the workflow by clicking on Workflow1 in
         the upper-left corner of the design surface.
      c. Right-click stateInProgress, and then click Add EventDriven.
      d. Rename the newly added event-driven
         activity eventOnTaskChanged.
      e. Drag an OnTaskChanged activity from the Toolbox, and drop it
         in eventOnTaskChanged. Name it onInProgressTaskChanged.
      f. Set the CorrelationToken property to InProgressToken.
         g. Click the ellipsis in the TaskId property, and then bind this field to the
            existing member CreateInProgressTask_TaskId1.
         h. Click the ellipsis in the AfterProperties property, and bind this field to
            a new field (similar to steps 2f–g).
State machines work a little differently from the sequential workflow described
earlier. The sequential workflow used an OnTaskChanged activity within
a While activity to repeatedly check the PercentComplete field to see whether
the task was complete and the workflow should move on to the next step. A state
machine operates by using an event-driven paradigm, so a While activity is not
needed. Every time the task changes, the eventOnTaskChanged sequence of
activities is executed. In this example, if the in-progress task is marked as
complete, the state should transition from in-progress to technical review. To do
this, we use an IfElse activity and investigate the value of
the PercentComplete field. We access the PercentComplete field by using
the AfterProperties associated with the onInPrgressTaskChanged activity.
To transition the state from in-progress to technical review
   1. Determine if a state transition is necessary, as follows:
         a. Drag an IfElse activity from the Toolbox to the design surface, under
            the onInProgressTaskChanged activity.
         b. Select ifElseBranchActivity1, and then rename
            it ifInProgressTaskComplete.
         c. Set the Condition property to Declarative Rule Condition.
         d. Expand the Condition property.
         e. Click the ellipsis in the ConditionName property, click New, and then
            add a rule as shown in the following figure.

            Figure 12. Declarative rule condition for determining whether a
            task is completed
f. Click OK to close the Rule Condition Editor, and then click OK to
   close the Select Condition dialog box.
g. Drag a SetState activity from the Windows Workflow v3.0 tab in
   the Toolbox into the ifInProgressTaskComplete branch. Name
   it setStateTechReview.
h. Set the TargetStateName property to stateTechReview.

   Figure 13. Completed event-driven activity for the in-progress
   state
After completing the stateInProgress event-driven activity, when
you switch back to the state view, you can see that Visual Studio has
drawn a line between the in-progress state and the technical review
state. This line indicates a relationship between the states—specifically
that stateInProgress is capable of transitioning tostateTechReview.
One more thing to notice is eventDrivenActivity1, which was created
by default. Because stateInProgress is the initial
state,eventDrivenActivity1 is an activity that Visual Studio adds that
handles the event associated with workflow activation. This example,
however, does not need to implement any logic on workflow
activation.

Figure 14. SetState activity causes Visual Studio to display
relationships between states in design view
2. Right-click stateTechReview, and then click Add StateInitialization.
3. Add a CreateTask activity to stateInitializationActivity2, as follows:
      a. Drag a CreateTask activity from the SharePoint Workflow tab in
         the Toolbox into stateInitializationActivity2. Name the
         task CreateTechReviewTask.
      b. Create a correlation token by entering TechReviewToken in
         the CorrelationToken property for CreateTechReviewTask.
      c. Expand the CorrelationToken property, and then set
         the OwnerActivityName to stateTechReview.
      d. Click the ellipsis in the TaskId property.
      e. On the Bind to a new member tab, click Create Field, and then
         click OK.
      f. Click the ellipsis in the TaskProperties property.
      g. On the Bind to a new member tab, click Create Field, and then
         click OK.
      h. View the events associated with CreateTechReviewTask, and then
         double-click in the MethodInvoking event to generate a handler for
         it.
      i. Add the following code to this event handler.

         Visual Basic
         CreateTechReviewTask_TaskId1 = Guid.NewGuid()
         CreateTechReviewTask_TaskProperties1.Title = "Perform
         Technical Review"
         CreateTechReviewTask_TaskProperties1.DueDate =
         Date.Now.AddDays(1.0)
4. Right-click stateEditReview, and then click Add StateInitialization.
5. Add a CreateTask activity to stateInitializationActivity3, as follows:
      a. Drag a CreateTask activity from the SharePoint Workflow tab in
         the Toolbox into stateInitializationActivity3. Name the
         task CreateEditReviewTask.
      b. Create a correlation token by entering EditReviewToken in
         the CorrelationToken property for CreateEditReviewTask.
      c. Expand the CorrelationToken property, and then
         set OwnerActivityName to stateEditReview.
      d. Click the ellipsis in the TaskId property.
      e. On the Bind to a new member tab, click Create Field, and then
         click OK.
      f. Click the ellipsis in the TaskProperties property.
      g. On the Bind to a new member tab, click Create Field, and then
         click OK.
      h. View the events associated with CreateEditReviewTask, and then
         double-click in the MethodInvoking event to generate a handler for
         it.
      i. Add the following code to this event handler.

         Visual Basic
         CreateEditReviewTask_TaskId1 = Guid.NewGuid()
         CreateEditReviewTask_TaskProperties1.Title = "Perform
         Editorial Review"
             CreateEditReviewTask_TaskProperties1.DueDate =
             Date.Now.AddDays(1.0)
At this stage in the example, all that is left to do is to add event-driven activities to
the technical review and editorial review states. For the technical review state, an
event-driven activity is needed to watch for changes to the technical review task. If
the task is marked as "100% complete", then a decision needs to be made about
the state to transition the workflow to. To keep things simple, let's use
the Description field associated with the task item. If the text in
the Description field is equal to Passed Tech Review, the state will transition to
the Editorial Review state, otherwise the state will be moved back to the In
Progress state. For the Editorial Review state, we use the same methodology except
the state will be transitioned to the in-progress state or the completed state,
depending on the value of the Description field. Obviously, a real-world state
machine workflow has more complicated logic and more possible state transitions;
however, the implementation mechanics are the same.
To add event-driven activities to the technical review and editorial review
states
   1. Add an event-driven activity to the technical review state
      (stateTechReview), as follows:
          a. Go back to the state view of the workflow.
          b. Right-click stateTechReview, and then click Add EventDriven.
          c. Rename the newly added event-driven
             activity eventOnTechReviewTaskChanged.
          d. Drag an OnTaskChanged activity from
             the Toolbox into eventOnTechReviewTaskChanged. Name
             it onTechReviewTaskChanged.
          e. Set the CorrelationToken to TechReviewToken.
          f. Click the ellipsis in the TaskId property, and then bind this field to the
             existing member CreateTechReviewTask_TaskId1.
          g. Click the ellipsis in the AfterProperties property, and then bind this
             field to a new field.
   2. Determine whether the Review Task is complete, as follows:
          a. Drag an IfElse activity from the Toolbox to under
             the onTechReviewTaskChanged activity.
          b. Select ifElseBranchActivity1, and then rename
             it ifTechReviewTaskComplete.
          c. Set the Condition property to Declarative Rule Condition.
          d. Expand the Condition property, and then click the ellipsis in
             the ConditionName property.
      e. Select New, and then add a rule with the
         condition me.onTechReviewTaskChanged_AfterProperties1.Perc
         entComplete = 1.0.
      f. Click OK to close the Rule Condition Editor, and then click OK to
         close the Select Condition dialog box.
3. If the task is complete, determine the workflow's new state, as follows:
      a. Drag an IfElse activity from the Toolbox into
         the ifTechReviewTaskComplete branch.
      b. Rename the left ifElse branch ifTechReviewSuccess. Rename the
         right ifElse branch ifTechReviewFailed.
      c. Select ifTechReviewSuccess, and then set the Condition property
         to Declarative Rule Condition.
      d. Expand the Condition property, and then click the ellipsis in
         the ConditionName property.
      e. Select New, and then add a rule with the
         condition me.onTechReviewTaskChanged_AfterProperties1.Desc
         ription="<DIV>Approved</DIV>".
      f. Click OK to close the Rule Condition Editor, and then click OK to
         close the Select Condition dialog box.
      g. Drag a SetState activity from the Windows Workflow v3.0 tab in
         the Toolbox into the ifTechReviewSuccess branch.
      h. Name the set state activity setStateEditReview.
      i. Set the TargetStateName property to stateEditReview.
      j. Drag a SetState activity from the Toolbox into
         the ifTechReviewFailed branch.
      k. Name the set state activity setStateInProgress.
      l. Set the TargetStateName property to stateInProgress.

         Figure 15. Structure of the event-driven activity for the
         technical review state
4. Add an event-driven activity to the editorial review state (stateEditReview),
   as follows:
      a. Go back to the state view of the workflow, right-
         click stateEditReview, and then click Add EventDriven.
      b. Rename the newly added event-driven
         activity eventOnEditReviewTaskChanged.
      c. Drag an OnTaskChanged activity from
         the Toolbox into eventOnEditReviewTaskChanged. Name
         it onEditReviewTaskChanged.
      d. Set CorrelationToken to EditReviewToken.
      e. Click the ellipsis in the TaskId property, and then bind this field to the
         existing member CreateEditReviewTask_TaskId1.
      f. Click the ellipsis in the AfterProperties property, and then bind this
         field to a new field.
5. Determine whether the review task is complete, as follows:
      a. Drag an IfElse activity from the Toolbox to under
         the onEditReviewTaskChanged activity.
      b. Select ifElseBranchActivity1, and then name
         it ifEditReviewTaskComplete.
      c. Set the Condition property to Declarative Rule Condition.
      d. Expand the Condition property, and then click the ellipsis in
         the ConditionName property.
      e. Select New, and then add a rule with the
         condition me.onEditReviewTaskChanged_AfterProperties1.Perce
         ntComplete = 1.0.
      f. Click OK to close the Rule Condition Editor, and then click OK to
         close the Select Condition dialog box.
6. If the task is complete, determine the workflow's new state, as follows:
      a. Drag an IfElse activity from the Toolbox into
         the ifEditReviewTaskComplete branch.
      b. Rename the left ifElse branch ifEditReviewSuccess. Rename the
         right ifElse branch ifEditReviewFailed.
      c. Select ifEditReviewSuccess, and then set the Condition property
         to Declarative Rule Condition.
      d. Expand the Condition property, and then click the ellipsis in
         the ConditionName property.
      e. Select New, and then add a rule with the
         condition me.onEditReviewTaskChanged_AfterProperties1.Descr
         iption="<DIV>Approved</DIV>".
      f. Click OK to close the Rule Condition Editor, and then click OK to
         close the Select Condition dialog box.
      g. Drag a SetState activity from the Windows Workflow v3.0 tab in
         the Toolbox into the ifEditReviewSuccess branch.
      h. Name the set state activity setStateCompleted.
      i. Set the TargetStateName property to stateCompleted.
      j. Drag a SetState activity from the Toolbox into
         the ifEditReviewFailed branch.
      k. Name the set state activity setStateInProgress2.
      l. Set the TargetStateName property to stateInProgress.
   7. Return to the state view of the workflow.

      Figure 16. Workflow designer after completing the simple document
      state machine




There are many more steps to implementing a document review workflow with a
state machine instead of a sequential workflow, but the state machine gives you a
lot more flexibility. Although a document review workflow would not normally
involve more than a few iterations between technical review, editorial review, and
in progress, the fact is that the number of iterations is not known ahead of time. A
state machine is an elegant way to handle this because it does not make any
assumptions about the sequence of events. You could come close to simulating this
in a sequential workflow but it would involve a convoluted set of nested looping and
branching activities that would be hard to follow.
Figure17. Tasks created and completed over the life of an example
workflow




Deploying a Workflow
After you develop and debug your workflow, it is likely that you will need to deploy
the workflow to a different server or site collection (unless you are developing
directly on your production server, which is not recommended). To deploy your
workflow, perform the following steps.
To deploy the workflow
   1. Copy the DLL your workflow creates from the build directory (\bin\Debug\ or
      \bin\Release) to the global assembly cache of the target server.
   2. Create a directory in the FEATURES directory (typically, the path
      is drive:\Program Files\Microsoft Shared\Web Server
      Extensions\12\TEMPLATE\FEATURES). Drop both the feature.xml and
      workflow.xml files into the directory.
   3. Install the feature on your farm by using the following command-line
      statement: stsadm –o installfeature –name
      SimpleSequentialDocumentReview
   4. Activate the feature on a site collection by using the following command-line
      statement: stsadm –o activatefeature –name
      SimpleSequentialDocumentReview –url http://moss.litwareinc.com

Conclusion
Workflow development with Microsoft Visual Studio 2008 is greatly simplified to
provide a more traditional development experience: Visually design the workflow
structure, add code to handle events associated with workflow activities and the
functionality you want, and then press F5 to debug the workflow.
Workflows consist of activities. To develop a workflow, you add activities to the
workflow designer, set or configure the properties associated with each activity, and
then add any code you want to respond to events associated with activities.
Windows Workflow Foundation includes many activities designed to perform specific
types of tasks. Microsoft Office SharePoint Server 2007 includes additional activities
specific to SharePoint workflows. In Visual Studio, you add an activity to a workflow
by dragging it from the Toolbox and dropping it in the desired location on the
designer.
Some activities can be configured at design time, but you may often need to set
activity properties at run time, implement logic, or perform related tasks when an
activity occurs. To do this, you can attach event handlers to activity events, for
example, the Invoked event. Just as you would generate an event handler for a
control on a user control, you can generate an event handler for
the Invoked event just by double-clicking in the Invoked property value while
viewing the events associated with the activity in the Properties window.
Finally, debugging workflows by using Visual Studio 2008 is trivial compared to the
task in earlier versions of Visual Studio. Simply press F5 in Visual Studio to start
debugging the workflow. Visual Studio takes care of compiling the workflow,
deploying the workflow to Office SharePoint Server, associating the workflow with
your target document library or list, attaching to the W3WP process, and opening
an instance of Internet Explorer displaying the correct page (the document library
or list that the workflow is associated with). Previously in Visual Studio, you had to
perform all of these chores manually.
Delivering Modular SharePoint Workflow
Functionality (Part 1 of 2)
Summary: Examine the options, process, and benefits of adding support for
SharePoint workflows to your application, and for breaking that support into
components that clients can use to build their own workflows. This article is part 1
of 2. (21 printed pages)


Applies to: 2007 Microsoft Office system, Microsoft Office SharePoint Server 2007,
Microsoft Office SharePoint Designer 2007, Microsoft Visual Studio 2008
development system, Visual Studio Tools for Office (3.0)
Download the code sample that accompanies this article: Sample Code: Delivering
Modular Workflow Functionality in SharePoint Server 2007
Read Part 2: Delivering Modular SharePoint Workflow Functionality (Part 2 of 2)
Contents
      Overview of Delivering Modular Workflow Functionality
      Introduction to SharePoint Workflows
      Exploring the Options: SharePoint Designer and Visual Studio
      Customizing the Tools
      Additional Resources

Overview of Delivering Modular Workflow Functionality
A workflow represents a process from start to finish. Whatever the business
scenario, the workflow models the events, actions, and situations that make up the
process. For an independent software vendor (ISV) that process is often deeply
entwined with his or her application. For a customer relationship management
(CRM) vendor, that process might be creating a customer record. For a vendor of
legal software, the process might be approving a document or tracking matter
elements across partners to ensure proper billing. For a financial services software
vendor, the process might be the entering and approval of payroll data.
The details of the process do not matter. What does matter is that software
applications provide services to their users and, in some cases, provide a significant
competitive advantage to allow users to control how those services are consumed.
As part of this article, we introduce an example of a vendor who makes software for
managing patient information. In that scenario, the vendor's software tracks data,
documents, and forms related to a patient through many different treatments and
therapies across multiple healthcare providers, and potentially across multiple years
of service.
Because of the nature of the vendor's clientele (local government health
management offices), there are many legal and practical reasons why the vendor
cannot dictate the details of the case management process. For example, in one
local office, approval is required before services are authorized for any provider
located outside the local office jurisdiction. In another local office, approval might
be required only if the provider is located in a different state. In another example,
in one local office, case workers might maintain all information in paper files and
enter the required details into the case management system only every few days;
in another office located in a different city, all case workers might have laptop
computers, and all information is maintained electronically and is instantly uploaded
to the case management system.
As you can see, there are many different ways to use the same software. At its
core, the software tracks patients and their information. In practice, the software's
usage is quite different. Unless the maker of the software has the most market
share, it would be foolish for that vendor to dictate a universal process. A one-size-
fits-all process would need to be so open-ended and flexible that it would be
exceedingly difficult to configure and manage for the end user.
Instead, the best approach the vendor can take is to break the processes of the
application into components, and allow either the client or the vendor's professional
services division to construct a workflow for each specific client from those modular
pieces. Using our case-management example, the vendor might identify
components such as:
      Create New Patient
      Update Patient Contact Information
      Add Document
      Add Treatment
      Add Doctor or Provider
Using the first component (Create New Patient) as an example, the core application
defines the information that is required to create a patient record, and what
happens inside the application after that patient record is created. The benefit of
breaking required functionality into components is that the vendor can still maintain
that control over the internal processing of their core application while opening the
business process up to whatever each client needs to create a patient record. One
client can allow any case manager to create a patient record, while another allows
any case manager to enter the information for a new patient, but requires
supervisory approval before the patient record is actually created.
The possibilities are endless.
The goal of this article is to examine the options, the process, and the benefits of
adding support for SharePoint workflows to your application and breaking that
support into components that clients can use to build their own workflows. Much of
the functionality to build a workflow is provided by default in Microsoft Office
SharePoint Server 2007. What is missing from an ISV’s point of view is direct
integration with his or her specific product.
Introduction to SharePoint Workflows
Workflows are a new core functionality provided in Microsoft Office SharePoint
Server 2007 and Windows SharePoint Services 3.0 (collectively referred to as
Microsoft SharePoint Products and Technologies). Workflows can be used in both
Office SharePoint Server and Windows SharePoint Services. These workflows tend
to be people-centric, document-centric, or content-centric, which fits in well with
the SharePoint mantra of communications and collaboration.
Figure 1. Workflows connect people and content to support a process




SharePoint workflows typically connect documents or other content to people, and
vice versa. Examples of typical SharePoint workflow scenarios include the following:
      Review
      Approval
      Publishing
      Task Assignments
ISVs might not consider these workflow scenarios to readily accommodate the
support of their specific applications. However, these topics are broad, and though
Review and Approval might be broader scenarios, any of these workflows can be
applied to almost any scenario. Any content that is collected as part of your process
can be reviewed and approved before it is actually added to your core application.
Any part of your application that needs someone to perform some work can benefit
from task assignments.
Extending the core paradigm of SharePoint lists and document libraries, SharePoint
workflows are tied to SharePoint items—either items in a SharePoint list or
documents in a SharePoint library. In every case, the workflow will act on or
process against one of those two items.
After a workflow is associated with a list or library (either directly or by using a
content type), it is available for use by all items in that list or library, as shown in
Figure 2.




Figure 2. Workflows are available on SharePoint list or document library
items




This article focuses on the very modular components that make up SharePoint
workflows. These components are called activities or actions and conditions,
depending upon which tool is used to create the workflow. By default, Microsoft
SharePoint Products and Technologies provide 32 built-in actions or conditions and
53 built-in activities (some of these are provided by Windows Workflow
Foundation). The following list contains examples of these default components:
      SendEMail
      CreateTask
      Assign a To-Do Item
      UpdateListItem
      Created by a Specific User
      Title Field Contains Keywords
These built-in SharePoint activities and actions or conditions are generic, and
certainly will not integrate directly with a third-party application. Microsoft leaves
this task of creating product-specific components for integration to the ISVs. In this
article, we address the process for doing this.
To get started, you must first understand the options and tools that are available to
you for creating workflows.

Exploring the Options: SharePoint Designer and Visual Studio
In the world of SharePoint development, a rift exists between experienced
developers and power users. Developers tend to shun Microsoft Office SharePoint
Designer 2007, the product that replaced Microsoft Office FrontPage. They ignore
arguments about Office SharePoint Designer being a new product that improves on
Office FrontPage through its improved rendering engine and other elements. Power
users, administrators, new developers, and a few enlightened experienced
developers see SharePoint Designer for what it is: a tool to use to perform specific
tasks.
Whatever your personal feelings about the tool that is SharePoint Designer, as an
ISV you cannot ignore it. Your potential clients might be using SharePoint Designer,
and it is not going away. You might as well learn to work with it. Ignoring it or not
supporting it in the workflow extensions to your product means that you are
potentially leaving your product vulnerable to competition or losing sales
opportunities. Supporting SharePoint Designer for workflow can expand your
potential audience and make your product more competitive. In addition, including
support for SharePoint Designer, if you are already planning to support Microsoft
Visual Studio, is quite simple. Reaching a wider audience for a low investment
seems an easy choice to make.
In this article, we look at both SharePoint Designer and Visual Studio so that you
can understand how they work when building workflows, and how to use each of
your modular components. Both tool options enable you to create workflows;
however, they each have different audiences and capabilities. Remember that it is
your customers who will pick a tool to use, not you. Your job is to keep your
product’s potential audience as open as possible and that means supporting both
tools. Fortunately, doing so is quite easy. Let's look at the tools. We discuss their
support in Customizing the Tools.
Visual Studio
The Visual Studio development system provides the full toolkit for workflow
developers. If a specific type of functionality is possible to implement in a workflow,
you can create it with Visual Studio.

  Note:

This article assumes you have experience in .NET Framework architecture or
development, and are already familiar with Visual Studio.
SharePoint workflow integration is a minor functional addition to Visual Studio. It
won’t take you much time to understand the changes.
The primary new functionality in Visual Studio is the addition of the workflow
designer, shown in Figure 3.
Figure 3. Two views of the new workflow designer tool in Visual Studio
Visual Studio now also includes special components, described earlier,
named activities. Activities are the workflow components that deliver the modular
functionality we need. In Figure 3, each of the individual rectangles connected by
the arrows represents an activity.
At a very high level, the process of building a workflow in Visual Studio is as
follows:
   1. Add activities to the workflow designer palette.
   2. Configure the activities in the Visual Studio Properties window.
   3. Write the code you need to put things together.
That’s it; nothing overly complicated. The problem is always in the implementation
details for your specific workflow, which unfortunately are beyond the scope of this
article.
As this is an article on modular workflow components, let’s take a closer look at
activities. Activities are the building blocks of all Visual Studio workflows; they are
the Lego® blocks from which we build our workflow world. Windows Workflow
Foundation (WF) provides 31 activities; SharePoint Products and Technologies offer
an additional 22. We can build activities to add whatever functionality we require.
Technically, activities are simply .NET Framework controls with some specific
functionality. As we'll show, activities are developed as classes and deployed as
assemblies. They have properties that can be set, and they can interact with
anything—such as components, services, databases—that a .NET Framework
component can interact with.
Visual Studio Use By Workflow Builders
If you are building a workflow in Visual Studio, you are a developer. Components
you build that target Visual Studio can be used only by people who are familiar with
Visual Studio, and with writing code and packaging it for deployment. This gives
you a certain amount of freedom because you can reasonably assume that your
users understand custom software development. This doesn’t mean that you don’t
need to support them, or that you can write insufficiently clear error messages, use
weak graphics, or take any other type of development shortcut. It simply means
that you are building a component for developers who have an understanding of
what is happening behind the scenes.
You might be able to provide more technical information only in error messages
rather than in innocuous user-friendly error messages. But you still need to provide
a good user experience for your components. To a certain extent, this more
development savvy audience might be even more critical of the user experience
you provide as they likely have experience with other component suites and so
have greater expectations. When we build the example components later in this
article, we will keep this in mind and take steps to ensure the user experience is a
good one.
SharePoint Designer
SharePoint Designer is a multi-faceted tool that can be beneficial to all users, from
power users and developers to interface designers. As with any tool, if SharePoint
Designer is used properly, it provides significant value. If not, it can cause
problems.
We’ll spend a bit more time walking through SharePoint Designer because it is a
new tool and likely less familiar to most architects and developers. Visual Studio,
however, while it changed with the addition of the workflow tools, is still Visual
Studio; it should not be wholly new to any experienced .NET developer or architect.
From a strictly-workflow point of view, SharePoint Designer provides a basic
intuitive interface to build smaller scale, more simplistic workflows. Understand that
this is not a slight on the tool; it is a statement of fact. Yes, you can use the tool to
build large, complex workflows, but as you’ll see, we don't recommend this.
You build SharePoint Designer workflows by using a wizard-like interface, as shown
in Figure 4.
Figure 4. SharePoint Designer workflows based upon a wizard-like
interface
SharePoint Designer workflows consist of the following seven constructs:
      Steps: A group of actions and conditions used to provide structure to the
       workflow.
      Conditions: The situations that indicate when to execute a specific Step in a
       workflow. SharePoint Designer provides nine default conditions, and it is
       possible to create and add your own.
      Actions: The functionality that is implemented in a Step. SharePoint
       Designer provides 23 built-in actions, and again, you can also create your
       own.
      Workflow Lookups: Functionality that allows you to retrieve information
       from other SharePoint items without writing any code.
      Variables: Standard programming variables that are used to store values.
       Examples include String and Number.
      Initiation Forms: Items that allow you to collect information from the user
       who initiates your workflow.
      Information Types: Similar in function to Variables, but Variables can also
       be used to define the interface presented to users to collect the data that is
       stored. Examples include Multiple Lines of Text and Choice.
To create SharePoint Designer workflows, you need to master these seven
constructs. We won't go into details about creating a SharePoint Designer workflow
here, as that is not within the scope of this article. However, Figure 4, shown earlier
can give you a general understanding of the possibilities and the process.
SharePoint Designer Use By Workflow Builders
Users of components you build with SharePoint Designer are likely to be quite
different from users of components you build with Visual Studio. This is due simply
to the different audiences for these tools. SharePoint Designer workflow users are
typically not highly technical. These builders will anticipate a very user-friendly,
wizard-driven interface that can walk them through the process of building and
deploying a workflow without requiring that they have much development
experience.
However, there are technical limitations to using SharePoint Designer for any
enterprise endeavors. Because this article does not address how to decide whether
your organization should use SharePoint Designer, we’re not going to discuss the
limitations here. We do address using SharePoint Designer because undoubtedly
some of your current customers or potential customers will be supporting it.
It is important that you keep this distinction in mind.

Customizing the Tools
With a basic understanding of the workflow landscape, we can now examine how
ISVs can provide additional value for their products by extending them through the
creation and support of modular components. The ultimate goal of this article is to
give you an understanding of the extension possibilities that either Visual Studio or
SharePoint Designer provide.
The extension options available to us, as we described earlier, are the following:
      Visual Studio activities
      SharePoint Designer actions
      SharePoint Designer conditions
Although SharePoint Designer supports other constructs (for example, Steps,
Lookups, and Variables), they are not available to us to extend or customize. While
it might appear that this limits your options, we will show that you will have more
than enough opportunity for extension. It might also appear problematic to have
three distinct options available to you. But you’ll see that the options are extremely
similar and in fact build upon each other.
Creating an Activity
Let's start by creating a custom activity for use with Visual Studio; the SharePoint
Designer action we build later will be a relatively simple extension of this activity.
The activity we build will allow workflows to update a proprietary software
application via a Web service with status information based upon a document
review process that varies from one installation of the product to another.
Introducing the Scenario: Contoso Software
Our scenario involves Contoso Software, a small ISV that produces CaseTrak.
CaseTrack is case management software designed specifically for local-government
mental health offices to manage information about patients diagnosed with mental
or behavioral disabilities. We assume that over the last several years, a near-
epidemic level increase in the number of autism diagnoses in young children has
put a significant strain on the mental health offices, and has resulted in a decrease
in their ability to manage cases effectively.
In this scenario, CaseTrak streamlines much of the case management process. As
part of their go-to-market strategy, Contoso has done research and determined
that a significant number of mental health offices use Windows SharePoint Services
3.0 to manage documents and provide a central location for employees to access
information. Contoso has set a strategic direction for their product to integrate with
Windows SharePoint Services. Initial efforts have produced Web Parts and a rich
Web service API that can provide read/write interaction between CaseTrak and
Windows SharePoint Services.
For their next major product release, Contoso is interested in facilitating integration
between CaseTrak and Windows SharePoint Services to support the case-review
process. The case-review process as it is exposed through the Web Parts currently
is entirely manual. Case managers need to remember to initiate the process and
track it throughout its lifecycle. This often causes error and missed deadlines.
Contoso has several requests from customers to make this easier. Their initial
design called for a single monolithic workflow controlled entirely by CaseTrak. Every
client would follow the same core process. Contoso designed several "extensibility
points" into the workflow to allow customers some ability to customize the workflow
to their specific needs.
Upon review with several key clients, Contoso realizes that this approach will not
work for several reasons:
Different regulations apply to the case-review process and even within those laws,
there is a lot of opportunity for offices to handle things slightly differently.
Clients using Windows SharePoint Services are accustomed to its flexibility and
interface. Forcing them into a different tool just for the case management process
is counterproductive.
IT departments at client locations are also resistant to adding another workflow
engine to their environment that they must support
Because of these concerns, Contoso’s product architecture group has proposed
delivering a modular set of components that either the client or Contoso’s own
professional services division can use to build Windows SharePoint Services
workflows to the exact specifications of each client and while still taking full
advantage of the power of CaseTrak.
The following sections explore how Contoso does that.

  Note:

Another benefit that Contoso will realize from producing custom activities is the
ability to have all of their CaseTrak activities adopt a different look and some
additional functionality from the rest of the default activities. Their product
marketing department sees a high value in extending their brand into this new
area.
Digging into the Scenario
In this scenario, we will be the developer for Contoso Software who is tasked with
creating the workflow activity. Before we can really get started writing code, we
need to make sure our environment is set up properly. There are numerous
resources available on the Web that provide detailed information about setting up a
proper SharePoint development environment, so only a simple list of the items
you’ll need to have installed follows:
      Windows Server 2003 or Windows Server 2008
      Microsoft .NET Framework 3.0
      Microsoft .NET Framework 2.0
      Visual Studio 2008
      Windows SharePoint Server 3.0 or Microsoft Office SharePoint Server 2007
Notice there is no actual requirement for working on a SharePoint platform for this
part of our activity because all we are doing here is building a component that
operates under WF. As a SharePoint workflow is built upon WF, this means that the
component we build will also work in SharePoint Server or Windows SharePoint
Server. Item five is on the list just for testing our activity later on.
A WF activity consists of between one and seven individual classes, as follows:
      ActivityCodeGenerator: Allows you to insert code into the activity during
       compilation.
      ActivityDefinition: The primary class of the activity. It controls what the
       activity actually does and is the only required class. If the other classes are
       not included in your activity assembly, default values are used.
      ActivityDesigner: Controls the structural appearance of the activity at
       design time in Visual Studio for non-theme elements.
      ActivitySerializer: Provides functionality for custom serialization.
      ActivityTheme: Controls color and other theme elements of the activity’s
       appearance in Visual Studio.
      ActivityToolboxItem: Used in Visual Studio to respond to events triggered
       when the activity is added to a workflow and also to control the appearance
       of the activity in the Visual Studio Toolbox.
      ActivityValidator: Verifies activity properties at both run time and design
       time.
Because this activity will be part of our packaged product, which clients will see and
interact with, we will use most of the classes
(specifically, ActivityDefinition, ActivityDesigner,ActivityTheme, ActivityTool
boxItem, and ActivityValidator). Remember, though, that the only required class
is the default ActivityDefinition class.
Code for the ActivityDefinition Class
The first piece of code to write for our activity is the one required
class: ActivityDefinition.
To create the ActivityDefinition class
   1. Start Visual Studio, and then create a Workflow Activity Library project
      (appropriately found under Workflow in the list of project types).
   2. Name the project CaseTrak.Activities.
   3. After the project opens, rename the default Activity1.cs something more
      meaningful (for example, StatusUpdater.cs). Visual Studio prompts you to
      rename all references; clickOK.
        We will still need to manually rename one entry in the Activity Designer
        generated code region within the StatusUpdater.Designer.cs file.
   4. Before we write any code, in Project Properties set your project to be strong
      named.
   5. Follow your company’s code-signing policies for configuring the proper key.

          Note:

         We recommend that your company adopt a code-signing policy if one is not
         already in place.
   6. Unless you will be using some of the capabilities specific to the .NET
      Framework 3.5, you should also change the Target Framework to 3.0.
Now you can start adding code.
Code for the Execute Method
The first line of code we are going to add is an override of the Execute method.
C#
protected override ActivityExecutionStatus
       Execute(ActivityExecutionStatus context)
This method is required because it is called by the WF host (SharePoint Server or
Windows SharePoint Services) when it is time to run the activity.
As you can see in the previous method signature, the Execute method returns a
value from the ActivityExecutionStatus enumeration, as follows:
       Canceling. Activity was ended prematurely
       Closed. Activity has finished its tasks
       Compensating. Rolling back changes
       Executing. Activity is still running
       Faulting. An error has occurred
       Initialized. Internal use only; you won't use it in your code
In most cases, the method returns a value of ActivityExecutionStatus.Closed.
The function of this activity is to update CaseTrak with the status of a case review
process. CaseTrak supports five statuses for case reviews:
        Open
        Closed
        Pending
        Deferred
        In Process
As part of the first wave of Windows SharePoint Services integration, your Web
service API exposes a CTSetCaseReviewStatus method, which your activity will
call. As you have likely guessed, this method handles the process of changing the
status of a Case record. It takes the ID string for the Case record and an integer
Status value and returns a Boolean indicator as to whether it succeeded.
C#
public bool CTSetCaseReviewStatus(string sCaseID, int iStatus)
The details of that Web service are not pertinent to this article. In your application’s
API, you will have any number of Web services available to perform the required
functionality. For the sake of completeness, the Web service project is included with
the source code that accompanies this article (see Additional Resources).
The core code for the Execute method for this activity is relatively simple.
C#
try
{
        ct.CTSetCaseReviewStatus(CaseID, Convert.ToInt32(CTStatus));
}
catch (Exception ex)
{
    //See full code listing
(http://code.msdn.microsoft.com/modularworkflow) for an error handling
event.
}
return ActivityExecutionStatus.Closed;
For now, we leave the catch block empty. The full code listing adds some error
handling in the form of an event handler, but we can hold off on that for now.
These couple of lines accomplish the work of this activity: Call the Web service
(ct is the Web service proxy object, which is declared elsewhere), cast the integer
value we received for the iStatus parameter to the appropriate CTStatus enum
value, and tell the workflow host (Windows SharePoint Services) that we’re
finished.
Code for the Properties
Looking at the previous Web service method call, you can see a reference to two
other variables: CaseID and Status. These are simply properties that are a part of
our Activity class.
C#
private string _caseID;


[DesignerSerializationVisibilityAttribute
     (DesignerSerializationVisibility.Visible)]
          [BrowsableAttribute(true)]
          [DescriptionAttribute("Unique identifier of the current
Case")]
          [CategoryAttribute("CaseTrak Configuration")]
          public string CaseID
          {
              get { return _caseID; }
              set { _caseID = value; }
          }


          private CTStatusType _iStatus;


[DesignerSerializationVisibilityAttribute
     (DesignerSerializationVisibility.Visible)]
          [BrowsableAttribute(true)]
          [DescriptionAttribute("Status designation of the current
Case")]
          [CategoryAttribute("CaseTrak Configuration")]
          public CTStatusType CTStatus
          {
              get { return _iStatus; }
              set { _iStatus = value; }
          }
Notice that the Status property is of type CTStatusType. This is an enumeration
of the valid statuses listed earlier.
C#
public enum CTStatusType
{
    Open=1,
    Closed=2,
    Pending=3,
    Deferred=4,
    InProcess=5
}
A benefit of using enumerations for values is that the activity will automatically
render this property as a drop-down list of choices in the Visual Studio Properties
window (Figure 5).
Figure 5. Custom Properties added to the activity as seen by developers in
Visual Studio




At this point, we have a functionally complete activity that could be used to build a
Visual Studio workflow. It exposes two properties that allow the workflow developer
to specify the current Case and also the status to set the Case to. Exactly how
those values are arrived at is highly dependent upon the client for which this
workflow is being built, and presents a good example of why we are exposing the
functionality of our application as modular components.
Remember Visual Studio developers will likely be a more demanding audience.
Presumably, they are familiar with other activities for building workflows and will
expect that our activity provides at least that much functionality. So let’s circle back
and enhance our activity.
Event Handlers
Most of the built-in activities support at least one customizable event, simply
named MethodInvoking. As the name implies, this event is raised when the
activity is invoked, before it actually does its work. Experienced workflow
developers will expect that our activity provides the same functionality.
Event handlers are added as dependency properties.
C#
public static DependencyProperty MethodInvokingEvent =
    DependencyProperty.Register("MethodInvoking",
typeof(EventHandler),
     typeof(StatusUpdater));



[DesignerSerializationVisibility(DesignerSerializationVisibility.Visib
le)]
[Description("The MethodInvoking event is raised before CaseTrak is
updated with the new status.")]
[Browsable(true)]
public event EventHandler MethodInvoking
{
     add { base.AddHandler(StatusUpdater.MethodInvokingEvent, value); }
    remove { base.RemoveHandler(StatusUpdater.MethodInvokingEvent,
value); }
}
With the MethodInvoking dependency property declared and registered, the only
thing that remains to do is to raise the method. We do this by adding the following
line to the Executemethod as the first line, right above the try.
C#
base.RaiseEvent(StatusUpdater.MethodInvokingEvent,this,EventArgs.Empty
);
If you look at Figure 5, you’ll see the MethodInvoking property exposed in the
Visual Studio Properties window. Whatever method name the developer sets as this
property value is now executed before the activity does any other work. The other
property shown in Figure 5, CaseTrakError, is another event handler that is
included in the full code listing that accompanies this article. It performs a function
similar to MethodInvoking except that it allows the workflow developer to specify
an event to be called in case an error is returned fromCaseTrak.
We now have a functionally complete activity that provides some functionality that
workflow developers expect. At this point, we could package and deploy our
activity. Instead, we’re going to take a few extra steps to really make our activity
shine.
Code for the ActivityValidator
Like most applications, CaseTrak doesn’t respond well to being given information
that is not valid or that is incomplete. In fact, it won't work if you attempt to set the
status of a case without specifying both the CaseID and the new Status. For this
reason, it is important that our activity have functionality that ensures that the
workflow developer using it provides a value for the
required CaseID and Status properties.
We do this by using the ActivityValidator class.
There is one core method we’ll override in this class, which is appropriately
named Validate.
C#
public override ValidationErrorCollection Validate(ValidationManager
manager,object obj)
{
     ValidationErrorCollection activityErrors = base.Validate(manager,
obj);
       StatusUpdater ctsu = obj as StatusUpdater;
       if ((null != ctsu) && (null != ctsu.Parent))
       {
            if (ctsu.CaseID == null)
            {

activityErrors.Add(ValidationError.GetNotSetValidationError("CaseID"))
;
            }
       }
}

    Note:

In the full source code listing included with this article (Sample Code: Delivering
Modular Workflow Functionality in SharePoint Server 2007), you can see how to
handle dependency properties, as it is slightly different from the simple properties
we address here.
The code for this method is still pretty straightforward. It checks the various
properties that must have values to see if they contain them. If they do not, it adds
a new validation error to the ValidationErrorCollection object for each property
that fails validation and returns that collection. The end result of this process is to
display a notification to the workflow developer that indicates things are not quite
right, as shown in Figure 6.
Figure 6. Validation errors shown to Visual Studio workflow developers

With the ActivityValidator class in place, all we need to do is register it with
our ActivityDefinition. We do this by decorating the ActivityDefinition class with
an attribute that references our validator class.
C#
[ActivityValidator(typeof(StatusUpdaterActivityValidator))]
Finally, we're ready to enhance the appearance of our activity and make it stand
out. We tackle this by using two
classes: ActivityDesigner and ActivityDesignerTheme.
Code for the ActivityDesigner and ActivityDesignerTheme
If you're observant, you have already noticed the look of our activity in Figure 6.
We show it again in Figure 7, this time with a view of what the activity would like
without these customizations. You can decide which one you like better.
Figure 7. Two views of the custom activity: one customized (bottom), one
not (top)




Notice the following in the customziations we've made:
      The customized design is wider to provide room for the CaseTrak logo on the
       left, and ensures that the name of the activity doesn't wrap onto multiple
       lines in the workflow designer the way the default activities does. A minor
       point, perhaps, but it does give our activity a more professional look.
      The addition of the CaseTrak logo (Figure 7a) helps to tie all of the CaseTrak
       activities together.

       Figure 7a. CaseTrak logo
        The red and black theme of the CaseTrak logo is carried into the activity
         background.
        Although less noticeable, we have also changed the placement of the text
         and image within the activity.
These elements all combine to produce an activity that is more visually appealing
than the default activities. Add to this the fact that all CaseTrak activities can easily
be made to use this look, and you have something that your product marketing
department will take notice of.
Accomplishing this appearance is made quite simple by using two distinct classes.
Let's look at the simpler of the two first: ActivityDesignerTheme. This class is
primarily responsible for the fonts and colors used to draw the activity. All of the
work in this class takes place in the constructor.
C#
public CaseTrakActivityDesignerTheme(WorkflowTheme theme): base(theme)
{
         BackColorStart = Color.Red;
         BackColorEnd = Color.Black;
     BackgroundStyle =
System.Drawing.Drawing2D.LinearGradientMode.ForwardDiagonal;
         ForeColor = Color.White;
}
Easily enough, all we do here is set our foreground and background colors and the
background style.
We achieve the rest of our enhanced appearance by using
the ActivityDesigner class. This class is responsible for the mechanics of the
Activity Design: the size and placement of the rectangles that bound the activity
and the text and image contained within the activity.
The first method we look at is OnLayoutSize, which sets the overall dimensions of
the activity.
C#
protected override Size OnLayoutSize(ActivityDesignerLayoutEventArgs
e)
{
         base.OnLayoutSize(e);
         return new Size(150, 45);
}
As you can see, it simply returns a new Size construct with the dimensions we
want; in this case, 150 pixels wide and 45 pixels high (the default activities render
at 91 pixels by 43 pixels.)
After the overall size of the activity is set, the rest of the display pieces are
controlled by two distinct rectangles within the activity
frame: ImageRectangle and TextRectangle.
C#
protected override Rectangle ImageRectangle
{
      get
      {
            Rectangle rectActivity = this.Bounds;
            Size size = new Size(20, 20);
            Rectangle rectImage = new Rectangle();
            rectImage.X = rectActivity.Left + 5;
          rectImage.Y = rectActivity.Top + ((rectActivity.Height -
size.Height) / 2);
            rectImage.Width = size.Width;
            rectImage.Height = size.Height;
            return rectImage;
       }
}
protected override Rectangle TextRectangle
{
      get
      {
            Rectangle rectActivity = this.Bounds;
            Size size = new Size(130, 40);
            Rectangle rectText = new Rectangle();
            rectText.X = this.ImageRectangle.Right + 5;
            rectText.Y = rectActivity.Top + 2;
            rectText.Size = size;
            return rectText;
      }
}
Each of these methods merely performs some simple calculations to determine the
placement of the Image and Text within the activity.
The final piece of this class is responsible for adding the CaseTrak logo into the
activity. We take care of this in the Initialize method of
the ActivityDesigner class.
C#
protected override void Initialize(Activity activity)
{
      base.Initialize(activity);
     Bitmap img =
CaseTrak.Activities.Properties.Resources.CaseTrakIcon16;
      this.Image = img;


      //Adding our custom Verb.
     verbAbout = new ActivityDesignerVerb(this,
DesignerVerbGroup.Edit,
           "About", new EventHandler(ShowAboutHandler));
      Verbs.Add(verbAbout);
}
The JPEG used for the logo is loaded into the Activity assembly as an embedded
resource.
You likely noticed one additional thing in the Initialize method:
the ActivityDesignerVerb. Figure 8 shows the end result of these two lines of
code.
Figure 8. Adding options to the Activities context menu
The code for the ShowAboutHandler event handler is simple.
C#
private void ShowAboutHandler(object sender, EventArgs e)
{
     MessageBox.Show("CaseTrack(tm) Status Updater Workflow
Activity.\r\n\r\n (c) 2007, Contoso Software, Inc.\r\n",
"About",MessageBoxButtons.OK, MessageBoxIcon.Information);
}
This is a nice way to add some help text or, as we do here, a copyright message to
a custom activity. There are countless other uses for activity verbs, ranging from
launching custom wizards to configure activities to interacting directly with your
core application to extract test data—whatever your business needs dictate.
With that, all of the code is in place. All we need to do is tie the pieces together.
Again, we do that by decorating our classes with attributes.
Add the following attribute to the top of the ActivityDesigner class to tell it
which Theme class to use.
C#
[ActivityDesignerTheme(typeof(CaseTrakActivityDesignerTheme))]
Now, add the following attribute to the ActivityDefinition, either before or after
the Validator attribute we added previously.
C#
[Designer(typeof(StatusUpdaterDesigner))]
That takes care of jazzing up the look of our activity on the workflow designer
palette. We now have just one more place where we can add some pizzazz: the
Visual Studio toolbox.
Code for the ToolboxItem Class
As the name implies, the ToolboxItem class is responsible for the presentation
and actions of our activity on the Visual Studio Toolbox. Like
the DesignerTheme class, the action here takes place in the constructor.
C#
private StatusUpdaterToolboxItem(SerializationInfo info,
StreamingContext context)
{
      this.Deserialize(info, context);
      this.Description = "Update Case Status in CaseTrak";
      this.Company = "Contoso Software, Inc.";
      this.DisplayName = "CaseTrakStatus Updater";
      this.Bitmap = new Ã
Bitmap(CaseTrak.Activities.Properties.Resources.CaseTrakIcon16);
}
We need to tie our ToolBoxItem back to our activity and as shown previously, we
do this with an attribute added above the ActivityDefinition class declaration.
C#
[ToolboxItem(typeof(StatusUpdaterToolboxItem))]
As you might have guessed, the result of this customization is to add some
information about our activity when it is displayed in the Visual Studio Toolbox, as
shown in Figure 9.
Figure 9. Adding copyright and other information to the activity for display
in the Toolbox
  Note:

For this class, the image file loaded into the Toolbox must be 16 pixels by 16
pixels and 256 colors.
Summary for the Activity
We built a custom activity in this section. In the process, we made use of five
different classes to make our new activity look good and perform well. We
customized everything from the functionality to how the activity looks and acts in
Visual Studio. Along the way, we touched upon such diverse capabilities as custom
context menus, validation, and generating a common look and feel for all of our
company’s activities



Deploying and Optimizing a SharePoint Web Part
That Calls Excel Web Services
Summary: Learn how to deploy a Web Part by using deployment CABs, and how to
improve the appearance and configurability of a Web Part. (10 printed pages)
Applies to: Microsoft Office SharePoint Server 2007, Microsoft Office Excel 2007
Download: MOSS2007ExcelWebPart.exe
Watch the SharePoint 2007 Video: Excel Services Mortgage Calculator.
Contents
      Introduction to Deploying and Optimizing a SharePoint Web Part
      Creating a Deployment Project to Install Your Web Part
      Creating the CAB Project
      Deploying the Web Part and Adding It to a Web Part Page
      Improving the Appearance and Configurability of the Web Part
      Redeploying the Updated Mortgage Calculator Web Part
      Conclusion
      Additional Resources

Introduction to Deploying and Optimizing a SharePoint Web Part
In Using Excel Web Services in a SharePoint Web Part, you learn how to create a
Web Part that calls Excel Web Services. The next step is to package and deploy the
Web Part. This article describes how to build a deployment project that you can use
to deploy the mortgage calculator Web Part that you created. You also learn how to
configure and improve the appearance of a Web Part.

Systems Requirements
To create and run the samples, you need the following software installed on your
computer:
      Visual Studio 2005
      Microsoft Office Excel 2007
      Office SharePoint Server 2007

Creating a Deployment Project to Install Your Web Part
One of the easiest ways to deploy your Web Part to Office SharePoint Server 2007
is to create a CAB file that can be deployed by using the Stsadm.exe tool. In this
section, you create a CAB project in Visual Studio 2005 that will contain the
elements of your Web Part.
Creating Support Files for the CAB Project
Before you create a CAB project, you must create the following files in your
XlMortageCalc project:
      Manifest.xml, which specifies the contents of the CAB
      MortgageCalculator.dwp, which is a Web Part definition file that is used by
       Office SharePoint Server 2007
To create the Manifest.xml file
   1. In Solution Explorer, right-click the XlMortageCalc project, point to Add,
      and then click New Item.
   2. Select XML File, and name the file Manifest.xml.
   3. Click Add.
   4. Add the following content to the file:

       Xml
       <?xml version="1.0"?>
       <!-- You need only one manifest per CAB project for Web Part
       Deployment.-->
       <!-- This manifest file can have multiple assembly nodes.-->
       <WebPartManifest
       xmlns="http://schemas.microsoft.com/WebPart/v2/Manifest">
         <Assemblies>
           <Assembly FileName="XlMortgageCalc.dll">
           <!-- Use the <ClassResource> tag to specify resources like
       image files or Microsoft JScript files that your Web Parts use. -
       ->
           <!-- Note that you must use relative paths when specifying
       resource files. -->
             <ClassResources></ClassResources>


             <SafeControls>
                <SafeControl
                   Namespace="XlMortgageCalc"
                   TypeName="*"
                />
             </SafeControls>
           </Assembly>
        </Assemblies>
        <DwpFiles>
           <DwpFile FileName="XlMortgageCalc.dwp"/>
        </DwpFiles>
      </WebPartManifest>
To create the MortgageCalculator.dwp file
   1. In Solution Explorer, right-click the XlMortageCalc project, point to Add,
      and then click New Item.
   2. Select XML File, and name the file XlMortgageCalc.dwp.
   3. Click Add.
   4. Add the following content to the file:

      Xml
      <?xml version="1.0" encoding="utf-8"?>
      <WebPart xmlns="http://schemas.microsoft.com/WebPart/v2" >
           <Title>Mortgage Calculator</Title>
          <Description>Mortgage Calculator Web Part that uses Excel
      Services to calculate monthly mortgage payments.</Description>
          <Assembly>XlMortgageCalc, Version=1.0.0.0, Culture=neutral,
      PublicKeyToken=cf4fe2436d2bd078</Assembly>
           <TypeName>XlMortgageCalc.XlMortgageCalc</TypeName>
          <!-- Specify initial values for any additional base class or
      custom properties here. -->
      </WebPart>
  Note:

The PublicKeyToken must be set to the public key that is specified for your
XlMortgageCalc.dll file. Follow these steps to determine the public key:
1. Open a Visual Studio 2005 Command Prompt window.
2. Type sn.exe -T full path to your XlMortgageCalc.dll file.
3. Copy the public key token that is returned.

Creating the CAB Project
CAB projects are simple projects that gather several files from your Web Part
project into a single CAB file that can be deployed by Office SharePoint Server
2007, as shown in Figure 1.
Figure 1. Solution Explorer with CAB project displayed




To create a CAB project
   1. Start Visual Studio.
   2. On the File menu, point to New, and then click Project.
      The New Project dialog box appears.
   3. In the Project Type pane, from the Other Project Types node,
      select Setup and Deployment.
   4. In the Templates pane, click Cab Project.
   5. Name the CAB project XlMortgageCalcCab.
   6. Click OK.
Next, you add the necessary files to the CAB project.
To add files to the CAB project
   1. In Solution Explorer, right-click the XlMortgageCalcCab project.
   2. Point to Add, and then click Project Output.
   3. Press CTRL+C (to select multiple items) and then select the Primary
      output and Content files.
   4. Click OK.
   5. In Solution Explorer, again right-click the XlMortgageCalcCab project, point
      to Add, and then click File.
   6. Browse and select the XlMortgageCalc.dwp file that you created earlier.
   7. Save and build the solution.

Deploying the Web Part and Adding It to a Web Part Page
Follow these steps to deploy your Web Part to Office SharePoint Server 2007.
To deploy the Web Part to SharePoint Server 2007
   1. For ease of deployment, copy the XlMortgageCalcCab.cab file to the following
      location, where Office SharePoint Server 2007 is installed:
      C:\Program Files\Common Files\Microsoft Shared\web server
      extensions\12\bin
      This should be the same as the location of Stsadm.exe. Ensure that you
      update the path on your computer if it does not match the default location.
   2. Click Start, click Run, and then type cmd.
   3. Type cd "C:\Program Files\Common Files\Microsoft Shared\web
      server extensions\12\bin"
   4. Run the following command to deploy your Web Part:

      stsadm -o addwppack -filename XlMortgageCalcCab.cab -url
      http://localhost -globalinstall -force
   5. After the command returns with "Operation completed successfully," run the
      following command:
      iisreset /timeout:0
Your Web Part is now successfully deployed to Office SharePoint Server 2007; the
only remaining step is to add it to a Web page. In this case, you add it to the home
page, but the following steps work for any SharePoint page.
To add the Web part to a Web page
   1. Open your Web browser and browse to "http://YourServer" as a user who
      has administrative permissions to Office SharePoint Server 2007.
   2. Click Site Actions, and then click Edit Page.
   3. In the Right zone, click Add Web Part.
   4. In the Add Web Parts - Web Page Dialog page, at the lower-right corner,
      click Advanced Web Part gallery and options to display the Add Web
      Parts gallery.
   5. Click Server Gallery.
   6. In the Server Gallery, you see the mortgage calculator Web Part. Drag the
      mortgage calculator Web Part to the Right zone.

      Figure 2. Dragging the Web Part to the SharePoint home page




   7. At the top of the page, click Submit for approval.
   8. After the page refreshes, click Approve.
You should now have a working mortgage calculator on your Office SharePoint
Server 2007 home page that uses Excel Services to perform the actual calculation.
To change the calculation, you just update the workbook; no coding is involved.

Improving the Appearance and Configurability of the Web Part
You now have a working mortgage calculator Web Part within Office SharePoint
Server 2007. Currently, it cannot be configured to use a different workbook
(located at a different location on your server) to perform the calculation. It is also
not a very good looking Web Part. By using a bit more code and some cascading
style sheet (CSS) styles, you can improve the appearance and configurability of the
Web Part so that you can specify the workbook to use through the Web browser.
Updating the Look of the Web Part
You might have noticed in the code that was added to the Web Part that the
following CSS classes were already specified:
      textInput
      total
      mainTable
      error
In this section, you add definitions for these CSS classes to your project.
To add CSS class definitions
   1. Inside your XlMortgageCalc class, add the following internal class
      (XlMortgageCalc.Constants):

       C#
       internal class Constants
       {
            public static string Styles = @"
           .mainTable { background-position: center center; background-
       attachment: fixed; background-image: url('_WPR_/house.jpg');
       background-repeat: no-repeat; background-color: #FFFFFF }
           .mainTable td, .mainTable input { font-family:Verdana; font-
       size:8pt }
            .total { font-weight:bold;width: 100; }
            .error { font-weight:bold; color:red; }
           .textInput { text-align:right; width: 75px; font-
       family:Verdana; font-size:8pt }";
       }
   2. At the beginning of the MortgageCalcPart_Load method, add the following
      lines of code:

       C#
       // Add our style sheet.
       HtmlGenericControl stylesheet = new HtmlGenericControl("style");
       stylesheet.InnerHtml = ReplaceTokens(Constants.Styles);
       this.Controls.Add(stylesheet);
You might notice that you are referencing an image, house.jpg, in the new styles. It
is included in the download, and is stored in the _WPR_ (Web Part Resources)
folder for this Web Part. The _WPR_ folder is determined at run time by
the ReplaceTokens method that is called in step 2. Next, you must add the
house.jpg image to the project, and to the CAB file.
To add an image to the project
   1. Drag the house.jpg image that is included in the download (or any other
      image you want to use) onto the XlMortgageCalc node in Solution Explorer.
   2. In the Manifest.xml file, replace the following line:

      Xml
      <ClassResources></ClassResources>
      With these lines:

      Xml
      <ClassResources>
                <ClassResource FileName="house.jpg"/>
      </ClassResources>
   3. Rebuild your solution to ensure that everything builds correctly.
Adding Web Part Properties to Make the Web Part Configurable
In this section, you add a Web Part property that can be configured in the browser
to specify the workbook that the Web Part should use to perform the calculation.
You call this propertyWorkbookUrl.
To add a Web Part property
   1. Open MortgageCalcWebPart.cs.
   2. In the XlMortgageCalc.Constants class, add the following constant:

      C#
      public const string WorkbookUrl = @"http://localhost/shared
      documents/mortgagecalc.xlsx";
   3. In the XlMortgageCalc class, add the following private member:

      C#
      #region Private Members
            private string _workbookUrl = Constants.WorkbookUrl;
      #endregion
   4. In the XlMortgageCalc class, add the following public property.
   Note that several attributes on this property tell Windows SharePoint
   Services how to display the property when it is shown in the Web Part Page
   task pane.

   C#
   #region Public Properties


   [Browsable(true),
   Category("Miscellaneous"),
   DefaultValue(Constants.WorkbookUrl),
   WebPartStorage(Storage.Personal),
   FriendlyName("Workbook URL"),
   Description("Enter the URL of the Excel workbook that should be
   used to perform the calculations for this Web Part.")]


   public string WorkbookUrl
   {
        get
        {
              return _workbookUrl;
        }
        set
        {
              _workbookUrl = value;
        }
   }
   #endregion
5. Finally, update the code in your project where this property should be used.
   Change the following line of code:

   C#
   sessionId =
   es.OpenWorkbook("http://TODOYourServer/Documents/MortgageCalc.xls
   x", "en-US", "en-US", out status);
   To be:
      C#
      sessionId = es.OpenWorkbook(this.WorkbookUrl, "en-US", "en-US",
      out status);
   6. Rebuild your solution to ensure that everything builds correctly.

Redeploying the Updated Mortgage Calculator Web Part
Now that you have updated your Web Part, you must redeploy it and configure it to
work in your environment. To do that, you first need to remove the original version
of the Web Part that you installed to SharePoint, and then install and configure the
new version.
To redeploy the Web Part
   1. For ease of deployment, copy the XlMortgageCalcCab.cab file to the following
      location on the computer where Office SharePoint Server 2007 is installed:
      C:\Program Files\Common Files\Microsoft Shared\web server
      extensions\12\bin.
      This should be the same location as Stsadm.exe. Ensure that you update the
      path on your computer if it does not match the default location.
   2. Click Start, click Run, and then type cmd.
   3. Type cd "C:\Program Files\Common Files\Microsoft Shared\web
      server extensions\12\bin"
   4. Run the following command to remove your old Web Part:

      stsadm -o deletewppack -name XlMortgageCalcCab.cab -url
      http://localhost
   5. Run the following command to install your new Web Part:

      stsadm -o addwppack -filename XlMortgageCalcCab.cab -url
      http://localhost -globalinstall -force
   6. After this command returns with "Operation completed successfully," run the
      following command:

      iisreset /timeout:0
Finally, you can configure your Web Part, as shown in Figure 3.
To configure the Web Part
   1. In the upper-right corner of the Mortgage Calculator Web Part, click the drop-
      down menu, and then select Modify Shared Web Part.
   2. Expand the Miscellaneous section (at the bottom of the task pane).
   3. Enter the correct value for the location of your workbook, and then click OK.
Figure 3. Configuring the Web Part properties for the Mortgage calculator
Web Part
Delivering Modular SharePoint Workflow
Functionality (Part 2 of 2)
Summary: Examine the options, process, and benefits of adding support for
SharePoint workflows to your application, and for breaking that support into
components that clients can use to build their own workflows. This article is part 2
of 2. (17 printed pages)
Applies to: 2007 Microsoft Office system, Microsoft Office SharePoint Server 2007,
Microsoft Office SharePoint Designer 2007, Microsoft Visual Studio 2008
development system, Visual Studio Tools for Office (3.0)
Download the code sample that accompanies this article: Sample Code: Delivering
Modular Workflow Functionality in SharePoint Server 2007
Read Part 1: Delivering Modular SharePoint Workflow Functionality (Part 1 of 2)
Contents
      Creating an Action
      Packaging the Activity or Action for Deployment
      Encapsulating Business Logic
      Extending Your API
      Packaging for Deployment
      Building the Feature
      Using STSDev
      Conclusion
      Additional Resources

Creating an Action
In Delivering Modular SharePoint Workflow Functionality (Part 1 of 2), we created
an activity that will work great in Visual Studio, but that will not work in Microsoft
Office SharePoint Designer 2007. So we're only part way to our goal. Fortunately,
creating a custom action for SharePoint Designer is a simple configuration process.
We need to write some XML, but no code.
The first thing we do is add an entry to the web.config file so that Windows
SharePoint Services or Microsoft Office SharePoint Server 2007 know about our
activity and how to load its assembly. This is very similar to adding
a SafeControls entry for a custom Web Part.

  Note:

I'll explain the entry we need to make here, and then walk through how to make it
manually in our development environment. However, before we can package our
activity or action for deployment, we need to ensure that our installation routine
adds the proper entry to the client's server. In Additional Resources, I'll mention
some tools that make the whole process much easier.

Packaging the Activity or Action for Deployment
Open the web.config file. Near the end of the file, you'll see a section
named <System.Workflow.ComponentModel.WorkflowCompiler>. Immediately
under that, you'll see a section named<authorizedTypes> that
contains <authorizedType> child tags. Add a new <authorizedType> tag for our
new action, as shown in the following example.
Xml
<authorizedType Assembly="CaseTrak.Activities, Version=1.0.0.0,
  Culture=neutral, PublicKeyToken=83d08a9b74a6ff8a"
  Namespace="CaseTrak.Activities" TypeName="*" Authorized="True" />
Remember you must replace the PublicKeyToken value with the value from your
strong name key or else this will not work.
Developers who are comfortable creating custom Web Parts will recognize that this
is nearly identical to a SafeControls entry. Someone who is not familiar with
a SafeControls entry should still be able to figure out the following pieces:
      Assembly: The full four-part name for your assembly, easily retrieved from
       a tool such as Reflector.
      Namespace: The namespace that is specific to your activity. For our sample
       scenario, this is CaseTrak.Activities.
      TypeName: Typically contains an asterisk to denote "all types"; however,
       you can list your specific class.
      Authorized: True to make your activity "safe"; otherwise, false, which
       seems like a waste of a web.config entry.
Now that we've told SharePoint Products and Technologies about our action and
that it's okay to run it, we need to tell SharePoint Designer about it. This is also
easy and involves writing only some light XML. Locate the path C:\Program
Files\Common Files\Microsoft Shared\web server
extensions\12\TEMPLATE\1033\Workflow. You should see a file named
WSS.ACTIONS in this folder; this file contains a wealth of information about custom
SharePoint Designer actions. Within this file, you will find an example of everything
that is possible using SharePoint Designer actions.
Unfortunately, the file is over 700 lines in length, and though it is only XML, it is a
little painful to wade through all of the options just to determine what you need to
know to build an action. In this article, we'll look at the more common options for
building custom actions. For a deeper look at all of the options (including a schema
definition), see Additional Resources.
The first thing you need to know about the WSS.Actions file is that like any other
SharePoint default file, you should never modify it. Instead, you must make your
own ACTIONS file in the same directory. Windows SharePoint Services and
SharePoint Server will read your file and load your custom actions into memory
with the default actions. To do this, simply create a file in the same directory, name
it something meaningful, and make sure that it has an .ACTIONS extension. For our
example, we will name the file CaseTrak.ACTIONS.
For our sample, simply add a text file to your solution in Visual Studio and add the
XML to it. Later when we discuss packaging and deploying, we'll handle getting this
copied to the proper place.
The following code example shows the full contents of our CaseTrak.ACTIONS file.
Though the contents are fairly self-explanatory, the Table 1 provides more detail.
Xml
<?xml version="1.0" encoding="utf-8"?>
<WorkflowInfo Language="en-us">
<Actions    Sequential="then" Parallel="and">
       <Action     Name="Update CaseTrak Status"
              ClassName="CaseTrak.Activities.StatusUpdater"
              Assembly="CaseTrak.Activities,
Version=1.0.0.0,Culture=neutral,
PublicKeyToken=bf813961d1f833f1"
              Category="CaseTrak Actions"
             AppliesTo="all">
            <RuleDesigner Sentence="Set CaseTrak Status for %1 to %2">
              <FieldBind Field="CaseID" Text="this Case"
DesignerType="string" Id="1"/>
              <FieldBind Field="CTStatus" DesignerType="Operator"
OperatorTypeFrom="DropDownMenu" Id="2" >
                  <Option Name="Open" Value="1"/>
                  <Option Name="Closed" Value="2"/>
                  <Option Name="Pending" Value="3"/>
                  <Option Name="Deferred" Value="4"/>
                  <Option Name="InProcess" Value="5"/>
             </FieldBind>
            </RuleDesigner>
         <Parameters>
         <Parameter Name="CaseID"       Type="System.String, mscorlib"
Direction="In" />
         <Parameter Name="CTStatus" Type="System.Int32, mscorlib"
Direction="In" InitialValue="5" />"</Parameters>
    </Action>
  </Actions>
</WorkflowInfo>
Table 1. Elements in the CaseTrak.ACTIONS file
Element         Notes

Action          Each action in our file has its own Action element, which explains
                the details for that action.
                The ClassName and Assembly attributes are self-
                explanatory. Category is straightforward, and as shown in the
                example, you can specify your own value to create your own
                category within the SharePoint Designer Action dialog box. The
                last attribute, AppliesTo, determines which type of list the action
                can be used against. Possible values are list, doclib, or all.
RuleDesigner SharePoint Designer workflows are based on the concept of
             sentences that describe the action to take. For example, a
             sentence could read "Send an Email to the document owner". This
             is more user-friendly than some other possible constructs. In
             SharePoint Designer, the sentence for our activity will read "Set
             CaseTrak Status for case <CaseID> to <Status>" where
             <CaseID> and <Status> are parameters (represented here by
             %1 and %2) which can be replaced with actual values by the
             workflow builder.
FieldBind       Each parameter (%n) from the sentence for our action is bound to
                a field, which specifies the name of the field, the text shown until
                 the parameter is assigned a value, the type of Designer shown
                 when setting a value for the parameter, and the ID of the field.
                 The first Field uses a simple string Designer; the second uses a
                 slightly more complex drop-down designer. For details on
                 possible DesignerType values, see Additional Resources.
Parameter        Each field in the example requires a corresponding Parameter
                 section. The Parameter entry provides details on how the data
                 from the field is handled. The Name of the parameter must match
                 a public property in the Action assembly. The other important
                 attribute here is the Directionattribute. This specifies whether the
                 parameter passes a value to the assembly (In), receives a value
                 from the assembly (Out) or is optional (Optional)—which only
                 applies to In parameters. As seen in the second parameter from
                 our example, you can also specify an Initial value via
                 the InitialValue parameter.
With those elements in place, all we need to do is reset IIS or recycle our
SharePoint Application Pool and our new action becomes available in SharePoint
Designer, as shown in Figure 10.
Figure 10. Custom action viewed in the SharePoint Designer list of actions




Now, when a user selects our action for use in a workflow, they see something
similar to what is shown in Figure 11.
Figure 11. Initial view of the custom action



As we saw in our ACTIONS file, the Case and InProcess are parameters that must be
replaced with actual values. The former is a simple string, and the latter a drop-
down list of valid choices, as shown in Figure 12.
Figure 12. Parameters specified for the action must be replaced with valid
values
With that, our custom action is finished. All we need to do to complete its
functionality is to create a custom condition for use in SharePoint Designer. We'll
address that next.
Creating a Condition
A custom condition is very similar to a custom action. The major difference is that
conditions typically are not going to start as activities or other assemblies because
they are a slightly different. The process of building a condition, however, is largely
the same as building an action:
   1. Build a custom assembly that encapsulates your logic.
   2. Deploy the assembly.
   3. Register and configure the condition so Windows SharePoint Services or
      SharePoint Server is aware of it
With that said, there is no reason not to, and many reasons to, include the code
necessary to support a condition in the same assembly as your action. It makes
things easier. If you are not developing actions, however, know that a condition can
exist in any assembly. I'll provide the details of what needs to be added to the
assembly shortly.
Continuing in the same scenario as our action/activity, our condition is part of
Contoso Software's CaseTrak application. In this case, we need to be able to
process case reviews only when a particular case is not on an administrative or
legal hold. Therefore, this condition must make a call back into CaseTrak to check
the hold status of each case. I'll walk you through the process here.
In code, a condition is simply a method that returns a Boolean value. To keep
things simple, we're going to add that method directly to our Activity assembly.
The important points for this method are that it must be static and that it must
return a Boolean value. Other than those two items, you can implement your
method in any way that properly calculates a Boolean return value.
In the example code included with this article, we simply return true in all cases. In
a real system, we would pass the CaseID parameter to a CaseTrak Web service and
get back a value that tells us whether or not the Case is on an administrative or
legal hold. In either case, we return that value back to the workflow and everything
continues processing appropriately.
The last step in configuring our condition is to register the condition so that
Windows SharePoint Services or SharePoint Server, and therefore SharePoint
Designer, are aware of it. Again, we do this by adding some simple XML into our
ACTIONS file, just below the root WorkflowInfo element.
Xml
<Conditions    And="and" Or="or" Not="not" When="If" Else="Else if">
    <Condition      Name="Case Not On Hold"
             FunctionName="CaseNotOnHold"
             ClassName="CaseTrak.Activities.StatusUpdater"
          Assembly="CaseTrak.Activities, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=bf813961d1f833f1"
          AppliesTo="all"
               UsesCurrentItem="false">
       <RuleDesigner Sentence="Case %1 is not on Hold">
          <FieldBind Id="1" Field="_1_" Text="CaseID"/>
       </RuleDesigner>
       <Parameters>
        <Parameter     Name="_1_" Type="System.String, mscorlib"
Direction="In" />
       </Parameters>
    </Condition>
</Conditions>
The elements in this XML are mostly identical to what we described earlier, so we
won't go into details again here. As before, there are many options
for Fields and Parameterselements. See Additional Resources for more
information.
With these elements in place, you reset IIS or recycle your Application Pool, and
then open SharePoint Designer. You can now use the new condition, as shown in
Figure 13.
Figure 13. Custom condition




  Note:

Depending on factors such as the nature of your change and how your server is configured, simp
Pool might not be sufficient because SharePoint Designer caches information. If you are making
file, and are not seeing the changes reflected in SharePoint Designer, try executing an iisreset c
the site in SharePoint Designer. If that still doesn't work, you must manually clear the SharePoin
file, close SharePoint Designer, navigate to the path Documents and Settings\[User_Name]\Lo
Data\Microsoft\WebsiteCache and delete the folder named for your site.
Summary of Customization Options
SharePoint workflow, by virtue of being built on top of Windows Workflow
Foundation (WF) is extremely flexible and extensible. By default, there is significant
value for building generic human-centric workflows. The benefit to an independent
software vendor (ISV) is the ease with which the power of WF can be extended to
integrate with their product. There is no reason to look elsewhere or build a
workflow engine for your product if integrating with SharePoint is an option for you
and your customers.
Whether workflow integration with your product will be built using SharePoint
Designer or Visual Studio is not a decision you have to make. As an ISV, it is
important for you to support both tools, for several reasons, as follows:
      Supporting SharePoint Designer but not Visual Studio is clearly not a viable
       option as you have to create a Visual Studio activity to create a SharePoint
       Designer action.
      Because it takes a small amount of effort to add SharePoint Designer
       support, there is little reason to support only Visual Studioand much to gain.
      By supporting both tools, you keep your client's options as open as possible.
       You are not forcing them to adapt to any one paradigm.

Encapsulating Business Logic
So far, we've walked through the technical aspects of how our customers will use
the components we give them. It's important to start with this understanding so
that we know what is possible technically. Now, however, we need to turn our
attention to our own software product. We need to understand the processes of our
application and be able to identify where it makes sense to carve out pieces of
functionality to expose as components. While it might very well be that we could
expose every piece of functionality offered by our application, it might not make
sense to do so.
Unfortunately for this article, each application, situation, and ISV is going to be
different. This will make it difficult to present hard-and-fast rules as to how you
should approach the process of exposing your application as components upon
which to build a process. Instead, we provide some general rules, discussing the
types of things you need to think about.
First and foremost, it is important to understand how your application can be used,
and its common usage scenarios.. This understanding might require you to interact
with whoever handles sales and marketing or market research for your company.
To get you started, here is an idea of the types of questions you need to ask:
      What information from our application would users like to expose to another
       application in their environment?
      Are there other applications in use at client sites that offer services that are
       complementary to our application that could be integrated to create a
       composite application or process?
      Are there other applications or processes in the client's environment that
       could feed or be fed by our application?
      Are there pieces of our application or process that users do not make use of?
You might also be able to get some of this information from whoever is responsible
for installing and supporting your application into client environments.
After you have answers to questions such as these, you need to do a technical
assessment of your application. You must understand the pieces of the application
that are candidates for exposure. If one portion of your application, for example,
had such unique or stringent security or auditing requirements for editing the
content, you might not want to expose it for editing. In this case, it might be
possible to simply offer read-only access to those pieces.
In another scenario, part of your application might need to handle large amounts of
data. Exposing this content to be extracted and pulled into another application
might not be feasible. Similarly, certain pieces of content might be valid only in
relation to other pieces of similar content. In this case, it might not make sense to
expose the content as individual elements.
The last scenario we'll examine is the idea of preserving proprietary business
concepts or algorithms. If exposing pieces of your application as a modular
component would reveal the inner workings to a client or competitor and diminish
or eliminate your competitive advantage, it obviously would not make good
business sense to do so. In that case, you can choose to prevent those elements
from being exposed, or can break them out in such a way as to minimize any
possible threat. You can still protect proprietary information in your application, and
expose only inputs and outputs that keep your proprietary elements as a black box.

Extending Your API
It was once safe to say that there were two primary methods to extend your .NET-
based product's API:
      By using Web services
      By using .NET Remoting
Which method you chose depended on several factors. If you chose Web services,
you traded decreased performance for cross-platform support. If you chose .NET
Remoting, you traded cross-platform support for increased performance. With
either option, we can keep to a services-based architecture by maintaining the
separation of our core business logic from the external processes that will access
our API.
At a high level, the options are functionally equivalent. Each allows for an
application or process running in one application space to make calls into our
application by using our defined API, to run in a different application space and
potentially on a completely different server. This means that we do not need to
install any piece of our core API anywhere but on the server that is running our
application. It also means that we have defined a contract and agreed to support it.
At any time in the future, we can make any change we want or need to our
application, and as long as we do not break the defined contract, we do not need to
worry about breaking any application that is using our API. We can also add new
functionality to what is specified in the contract provided that we do not change the
existing functionality.
Over the last several years, improvements in the performance and security of Web
services have led to their being declared the winner of the battle. Rarely does
anyone use .NET Remoting anymore; however, if that is the direction in which your
API extensibility has gone, rest assured that nothing here prevents you from
continuing down that path.
From our point of view, this simplifies things considerably: we extend our API by
wrapping Web services around it. Any functionality that needs to be exposed to the
outside world gets a Web service interface. We define the contract—the inputs and
outputs—and any application that can interact with Web services can immediately
begin integrating with our product.
From an ISV's point of view, that sounds pretty attractive. And the best part for this
article is that there is absolutely nothing that you need to do differently to enable
the workflow components you build to call into your Web services. Craft your Web
services as you need to for the rest of your application and let the components call
them as they need to.

Packaging for Deployment
Technically, packaging our components for deployment could easily be handled
differently from packaging most other SharePoint components. There is nothing
specific to Windows SharePoint Services or SharePoint Server about most of what
we've discussed. However, we are in fact developing for a SharePoint environment
and know that our components will be deployed to a SharePoint environment. So it
behooves us to keep SharePoint Products and Technologies in mind as we prepare
for deployment.
Because our components will be installed with various other SharePoint
components, our deployment should look and feel like any other SharePoint
deployment. This means we need to consider Features and solutions. There are
several approaches to building out your Feature and solution; the approach I'll take
here is one that seems to be emerging as the most common.
Before we get to that, let's review exactly what it is we need our deployment
process to do for our components. Our deployment process must:
   1. Install our assembly to the global assembly cache.
   2. Copy our ACTIONS file to the path Program Files\Common Files\Microsoft
      Shared\web server extensions\12\TEMPLATE\1033\Workflow.
   3. Update the web.config file with an authorizedType entry.
We can easily do all of this by using solutions and Features:
       Solutions excel at physically moving files, so we'll use a Solution to handle
        the first two tasks.
       Features allow us to execute code when they are activated or deactivated, so
        our Feature will handle the third task. One caveat is that our components are
        targeted at a level higher than an individual Web or site collection, and we
        want someone with some level of administrative permissions to manage
        these components. This means that we will scope our Feature to either a
        Web Application or a Farm level. You must decide which is appropriate for
        your situation or expect to allow the person who installs your application to
        decide which is appropriate for their environment.
Now let's build our Feature.

Building Our Feature
The Feature we build is going to be slightly different from many others that you
have probably created, as we will handle all of the work for our Feature in the
Feature Receiver. The Feature itself does nothing, so we won't have an elements
file, as we'll see shortly. Before we go too far, recall from our earlier list of
functionality that the Feature will handle the last task: Update the web.config file
with our authorizedType entry. Now let's build the Feature Receiver.
Building a Feature Receiver
A Feature Receiver is nothing more than a class that inherits from
the SPFeatureReceiver class, and implements the event methods we need. In our
case, we need only the event receiver for the FeatureActivated event, as shown
in the following code.
C#
public override void FeatureActivated(SPFeatureReceiverProperties
properties)
{
SPWebApplication wappCurrent =
(SPWebApplication)properties.Feature.Parent;
SPWebConfigModification modAuthorizedType = new
SPWebConfigModification();
modAuthorizedType.Name = "AuthType";
        modAuthorizedType.Owner = "CaseTrak.Actions";
      modAuthorizedType.Path =
"configuration/System.Workflow.ComponentModel.
WorkflowCompiler/authorizedTypes";
      modAuthorizedType.Type =
SPWebConfigModification.SPWebConfigModificationType.
        EnsureChildNode;
      modAuthorizedType.Value = @"<authorizedType Assembly=""
CaseTrak.Activities, Version=1.0.0.0,
         Culture=neutral, PublicKeyToken=bf813961d1f833f1""
         Namespace=""CaseTrak.Activities"" TypeName=""*""
         Authorized=""True"" />";
       wappCurrent.WebConfigModifications.Add(modAuthorizedType);
       wappCurrent.WebService.ApplyWebConfigModifications();
         }
If you recall, we need our Feature Receiver to add a child node to
the configuration/System.Workflow.ComponentModel.WorkflowCompiler/a
uthorizedTypes element within our web.config file. This code does this by working
with the SPWebConfigModification class. All we're doing is specifying the path
within the web.config file that we need to add our element to, and then the value of
the child node we need to add.
Xml
<authorizedType Assembly="CaseTrak.Activities, Version=1.0.0.0,
  Culture=neutral, PublicKeyToken=bf813961d1f833f1"
  Namespace="CaseTrak.Activities" TypeName="*" Authorized="True" />
There is no reason not to add this class to our Activity assembly, as both must be
deployed to the global assembly cache. You'll see in the example code that this is
exactly what I did. Compile the assembly and we can move on to the rest of the
Feature elements.
Feature.XML
Feature.xml is the SharePoint file that describes your Feature. This structure of this
file is mostly the same for each Feature you create, differing only in the actual
values for the elements. Create a blank XML file (just in the root of your Solution
for now, we'll move it in a few minutes), and then add the appropriate entries.
Xml
<?xml version="1.0" encoding="utf-8" ?>
<Feature
  Id="AB37234F-3EA1-DD38-AA21-652A894BC21A"
  Title="CaseTrak Workflow Components"
  Description="Install and activate components for use in Workflows"
  ImageUrl="CaseTrakLogo.jpg"
  Scope="WebApplication"
  Hidden="false"
  ReceiverAssembly="CaseTrak.Activities, Version=1.0.0.0,
Culture=neutral,Ã PublicKeyToken=bf813961d1f833f1"
  ReceiverClass="CaseTrak.Activities.FeatureReceiver"
  xmlns=http://schemas.microsoft.com/sharepoint/>
  <ElementManifests />
</Feature>
As always, you need to update your PublicKeyToken value.
Table 2 describes the elements of the Feature.xml file.
Table 2. Elements in the Feature.xml file
Element Name          Description

Id                    A GUID the uniquely identifies this Feature.
Title                 The name for the Feature, as it will appear in the user
                      interface (UI).
Description           The descriptive text that will appear under the Title in the
                      Feature list.
ImageUrl              The path to an image that will be shown in the list of
                      Features with your Feature name. This path is relative to
                      your Feature directory. You can make your components look
                      more professional by putting your company or product logo
                      here.
Scope                 The location this Feature will be deployed to. While valid
                      options for Features are Farm, WebApplication, Site,
                      or Web, notice that we will restrict this
                      to WebApplication because we want to control who can
                      manage the availability of our components. Setting this
                      toWebApplication or Farm will require that an
                      administrator have permissions at the Web application or
                      farm level respectively. This makes things a little more
                      secure for our components.
Hidden                A Boolean value to indicate whether the Feature is visible in
                      the UI.
ReceiverAssembly The four-part name of the assembly that contains our
                 Receiver. This does not have to be the same assembly as
                 your components, but that's how we do things in this
                 example.
ReceiverClass         The name of the Receiver class within our assembly.
Xmlns                 The XML namespace for the schema. For SharePoint Server
                       2007, this is
                       always http://schemas.microsoft.com/sharepoint/.

ElementManifest        Element that contains the location of the element manifest
                       file. The element is required, but we're not making use of an
                       element manifest file, so we can leave it blank.
That takes care of the Feature and Feature Receiver; now let's package it all into a
solution.
Solutions
Building a SharePoint solution is not a difficult process, but it is very exacting. You
need to set up all of the pieces exactly to build the .wsp (solution) file correctly,
and to enable correct deployment of your solution. We'll walk through the process
of building the .wsp file at the end of this section. Now, it is important to
understand the purpose and function of a solution package and to look at the
elements that compose it: the manifest file and the directive (.ddf) file.
Solution packages are simply a mechanism for deploying new functionality to
Windows SharePoint Services or SharePoint Server. However, they provide great
benefits for deployment. If you want your workflow components to look and act
their best in your application, you have to use them. Let's look at the process.
You can build your solution in two ways: manually or by using tools that automate
the process. Normally, I'm a big fan of tools because they can save you a lot of
time and effort. However, I think it is more important to understand what those
tools are doing for you, so we'll examine the manual process here. In Additional
Resources, I provide some links to a few tools that can take a lot of the pain out of
this process.

  Note:

We will focus on building a solution to address the needs of the components in this
article. For a great article about how to build building solutions in general, see Ted
Pattison's August 2007 Office Space column in MSDN Magazine, Solution
Deployment with SharePoint 2007.
Manifest File
The manifest file defines the solution and lists all of the elements that make up the
solution. Like Feature.xml and Workflow.xml, the manifest file for your solution is
an XML file, this time adhering to the Solution Schema. A sample manifest file looks
like the following.
Xml
<?xml version="1.0" encoding="utf-8" ?>
<Solution xmlns="http://schemas.microsoft.com/sharepoint/"
  SolutionId="79deac59-22ab-da1e-9d7a-1732d31cbe07" >
  <Assemblies>
     <Assembly DeploymentTarget="GlobalAssemblyCache"
Location="CaseTrak.Activities.dll" />
  </Assemblies>
  <TemplateFiles>
     <TemplateFile Location="1033\Workflow\CaseTrak.ACTIONS"/>
  </TemplateFiles>
  <FeatureManifests>
     <FeatureManifest Location="CaseTrak_Activities\Feature.xml"/>
  </FeatureManifests>
</Solution>
Table 3 provides details about the elements of the Manifest.xml file.
Table 3. Elements of the Manifest.xml file
Element                 Description

SolutionId              A GUID that uniquely identifies your solution.
Assemblies              Specifies to add one node for every assembly that is part of
                        your solution.
DeploymentTarget Tells the solution installer where to put the DLL. Valid
                 options are WebApplication or GlobalAssemblyCache.
Location                Tells the solution installer where to find your DLL.
TemplateFile            In this example, tells the solution installer where to find our
                        ACTIONS file within the .wsp file, and also where it needs to
                        be placed on the file system. The path here is relative to the
                        TEMPLATE folder.
FeatureManifest         Tells the Solution installer where to find your Feature.xml
                        file.
That's all we need for this example manifest file. There are quite a few other
options available. If you're curious, you can review the schema file in Solution
Schema.
Directive (.ddf) File
The .ddf file is the final piece necessary for building our solution. This is the file that
is used to define the structure of our solution file. During the process of building our
.wsp (solution) file, the MakeCAB utility (more on this in a moment) reads the .ddf
file and packages all of the files for as specified in the .ddf.

  Note:

Although our solution file has a .wsp extension, it is really nothing more than a
standard .cab file with a different extension. If you change the extension back to
.cab, you can open the file in Windows Explorer and examine the contents.
Our sample .ddf file looks like the following.

;*************
; This .ddf file specifies the structure of the .wsp solution cab
file.
;*************


.OPTION EXPLICIT
.Set CabinetNameTemplate=CaseTrak_Activities.wsp
.Set DiskDirectoryTemplate=CDROM
.Set CompressionType=MSZIP
.Set UniqueFiles="ON"
.Set Cabinet=on
.Set DiskDirectory1=Package


manifest.xml manifest.xml
bin\debug\CaseTrak.Activities.dll CaseTrak.Activities.dll
RootFiles\TEMPLATE\FEATURES\CaseTrak_Activities\feature.xml
CaseTrak_Activities\feature.xml
RootFiles\TEMPLATE\1033\Workflow\CaseTrak.ACTIONS
1033\Workflow\CaseTrak.ACTIONS
The top of the file sets up some variables that configure how the .wsp file is
generated and are generally self-explanatory. Table 4 describes the elements in the
.ddf file.
Table 4. Elements in the .ddf file
Element                      Description

CabinetNameTemplate Specifies the name of the resulting .wsp file.
DiskDirectoryTemplate Places all generated .cab files in a single directory
CompressionType              Specifies the algorithm used for compressing files.
UniqueFiles                  Indicates that all files in the .cab file must have unique
                             names.
DiskDirectory1               Specifies a subdirectory into which .cab files are placed.
Typically, the top part of the .ddf file is the same (except for
the CabinetNameTemplate parameter) for all solutions that you build.
The rest of the file is unique to the specific solution that you are building. It
specifies the files that will be packaged into the .wsp file, and the following:
      The first part of each line is the source location so that MakeCAB can read
       them to add them to the .cab file.

          Note:

       This location is relative to the current directory, which will typically be the
       location of the .ddf file or the location of the MakeCAB utility.
The second part of each line specifies the destination location of each file within the
.cab file. In the previous example:
      The Manifest.xml file and our DLL will be located in the root of the .cab file.
      The Feature.xml file will be in the root of our Feature
       (CaseTrak_Activities) folder.
      The ACTIONS file will be in a folder path 1033\Workflow. Remember that
       when the solution is deployed, this location is referenced in
       the TemplateFile element of Manifest.xml and is relative to
       the \Template folder.
For the files portion of your .ddf file, it is important that you include each
source/destination pair on one line. They are broken onto two lines in our listing
here only for readability.

  Note:

It is an emerging best practice to build a folder structure within your Visual Studio
solution that mirrors the structure of the SharePoint 12 folder (often referred to as
the "WSS Root" or "12 hive"). While not required, this is the approach we have
taken here. In addition, the various tools recommended in Additional Resources
follow a similar approach.
To understand the file system structure that is required for this .ddf file to work
properly, examine Figure 14. It shows a view of our project with all of the folders
and files laid out as the DDF and MakeCAB utility expects to find them. You'll need
to recreate this file structure within Visual Studio and copy the files to the
appropriate places. Notice that the Utilities folder contains a few batch files for
building and testing the solution file and the MakeCab.exe application. See
Additional Resources for information on how to download a copy of MakeCAB.exe,
as part of the Microsoft Cabinet SDK. The remainder of this solution is available in
the source code download for this article.
Figure 14. Directory structure required for solution




With that, the .ddf file is complete. We can move on to building the .wsp file.
Building the Solution File
The last step is to actually build the solution (.wsp) file. We've discussed how to
construct the files in our solution, and the file structure we need; now we can
create the solution file. Because we manually built our Manifest and Directive files,
we can't take advantage of the functionality provided by the PostBuildActions.bat
file provided by the Microsoft Office SharePoint Server 2007 SDK, which is okay
because we wouldn't have it available if we were just using Windows SharePoint
Services or SharePoint Server anyway. This means that we need to support only
one process, regardless of which SharePoint version we are using.
Building the .wsp file can be handled easily with two lines in our MakeCAB.cmd file
(available in the source code download).

cd ..
Utilities\MakeCab /F CaseTrak_Activities.ddf
After running this batch file, your .wsp file is available in
the DeploymentFiles\Package directory within your project folder. If you'd like to
take a look at the contents of the .wsp file, simply change the extension to .cab and
open it in Windows Explorer. Just make sure to change the extension back when
you are finished.
Wrapping Up Deployment
As mentioned at the beginning of our deployment discussion, it is important that
the deployment process for your workflow components look professional and like it
belongs with the rest of your application deployment. Because of this, the typical
batch files used for deployment (including the Deploy.cmd and the UnDeploy.cmd
files in the source code download, which are good for testing your solution package)
will not suffice. Instead, you must look into something a little more polished. See
Additional Resources for links to a few options.
We described the manual way of doing things here so that you understand what is
happening. I strongly recommend that you open the three .cmd files in the source
code download and review the steps they perform. This will help you understand
what is happening and, when you start using a tool, to understand and appreciate
what the tool is doing for you.

Using STSDev
Now that you've made it this far and have a good understanding of what it takes to
build custom activities, actions, and conditions, I have some good news for you.
You don't need to go through all of that pain again each time you want to build a
new one. There is a community-developed tool available on CodePlex (see
Additional Resources for the direct link) called STSDev. It includes an option to
select some options in a wizard-like interface and then have the tool generate a
complete activity, action, or condition with everything you need, as follows:
      All five Activity classes with stub methods in place
      Your ACTIONS file
      A Feature Receiver to add the AuthorizedType entry to the web.config file
      All deployment files (Feature.XML, Manifest.XML, .ddf, and .wsp).
I strongly recommend that you use this tool. It will save you time and aggravation.

Conclusion
Whew. This was a long process, but we've succeeded. That's it, we're finished. We
started this article with a somewhat vague idea of what we were getting ourselves
into, with a lot of hope and a little fear that things were going to be difficult. But
here at the end, we discover that things really aren't so tough after all.
Along the way, we managed to sidestep the argument of whether to support
SharePoint Designer or Visual Studio by realizing that we need to support both. We
learned about activities for Visual Studio and actions and conditions for SharePoint
Designer, and described the process of building all three AND making them stand
out from the run-of-the-mill components that lesser developers might create.
Finally, we closed out with how to package our components so that they can easily
be deployed along with the rest of our application with all the spit and polish of a
professional installation. Not too bad for an afternoon's work.
In all seriousness, the ability to extend SharePoint workflows is one of the most
exciting features of SharePoint as an application platform and one that ISVs should
look at quite seriously. By extending SharePoint workflow, you can easily build upon
an enterprise-class workflow engine to bring that power and reach to your
application. The SharePoint Products and Technologies are the crown jewels of the
Microsoft platform and being able to jump in and develop on that platform can only
enhance your application

				
DOCUMENT INFO