Sunday, September 12, 2010

Webparts Deploy

How to Deploy SharePoint WebParts

There are several ways to skin the Webparts deployment cat, each with a few pluses and minuses. 
Method 1 - manual
  • Copy assembly DLL to either
    - /bin directory for a given IIS virtual server (e.g., c:\inetpub\wwwroot\bin)
    - Global Assembly Cache (e.g., c:\windows\assembly)
  • Copy DWP file to C:\Inetpub\wwwroot\wpcatalog
  • Copy resources to
    - For GAC-registered parts, C:\Program Files\Common Files\Microsoft Shared\web server extensions\wpresources
    - For Web Parts in the /bin directory, C:\Inetpub\wwwroot\wpresources
  • Adjust web.config
    - Register as SafeControl
    - Select Code Access Security settings

Method 2: CAB File
  • CAB file should contain
    -Assembly DLL
    -DWP file(s)
    -Manifest.XML
    -Resource files (if needed)
  • CAB won't contain
    - Code Access Security settings
  • Server-side object model has methods for deploying such a CAB file
  • Deploy with STSADM.EXE
    Located in C:\Program Files\Common Files\Microsoft Shared\web server extensions\60\BIN
    Add it to your path
    Stsadm -o addwppack -filename filename [-globalinstall] [-force]

Method 3: MSI File via WPPackager
  • All of the features of CAB file deployment, but with
    - Code Access Security support
    - Ability to uninstall via Control Panel
  • Add additional files to project for use by WPPackager
  • Run WPPackager after project is built

SharePoint Best Practices For Begginers

SPSiteDataQuery Class
Imagine a scenario in which you want to run a single query against every list in the current site collection that has been created from the Announcements list type and return all list items that were created today. The following code sample demonstrates how to do this by creating an SPSiteDataQuery object, initializing it with the necessary CAML statements, and then passing it to the current SPWeb object’s GetSiteData method.

SPSiteDataQuery query = new SPSiteDataQuery();
query.Lists = @"";
query.ViewFields = @"";
query.Webs = "";

string queryText = @" ";


query.Query = queryText;

DataTable table = site.GetSiteData(query);

foreach (DataRow row in table.Rows) {
Console.WriteLine(row["Title"].ToString());
}



Using SPQuery to query specific items in the list 

To get back specific results within a list, you can use the SPQuery object. When you use an SPQuery object, you will create CAML statements to select specific data within the target list. To select announcements that have expired, you may want to use a query built with CAML statements, as shown in the following example:

SPQuery query = new SPQuery();
query.ViewFields = @"";
query.Query =
@"
";

SPList list = site.Lists["Litware News"];
SPListItemCollection items = list.GetItems(query);
foreach (SPListItem expiredItem in items) {
Console.WriteLine(expiredItem["Title"]);
}
You must specify the fields you want returned in the query by using the ViewFields property. Also note that you must specify the fields in terms of the field Name, and not DisplayName. If you attempt to access fields without specifying them in ViewFields, you will experience an exception of type ArgumentException

Enumerating thought the Fields excluding Hidden and read only fields
foreach (SPListItem item in list.Items) {
foreach (SPField field in list.Fields) {
if (!field.Hidden && !field.ReadOnlyField)
Console.WriteLine("{0} = {1}", field.Title, item[field.Id]);
}
}
foreach (SPListItem item in list.Items) {
foreach (SPField field in list.Fields) {
if (!field.Hidden && !field.ReadOnlyField)
Console.WriteLine("{0} = {1}", field.Title, item[field.Id]);
}
}
Checking if the List Exists and Adding a new list if it does not Exists 

using System;
using Microsoft.SharePoint;

class Program {
static void Main() {
using (SPSite site = new SPSite("http://localhost")) {
using (SPWeb web = site.OpenWeb()) {
string listName = "Litware News";
SPList list = null;
foreach (SPList currentList in web.Lists) {
if (currentList.Title.Equals(listName,
StringComparison.InvariantCultureIgnoreCase)) {
list = currentList;
break;
}
}

if (list == null) {
Guid listID = web.Lists.Add(listName,
"List for big news items",
SPListTemplateType.Announcements);
list = web.Lists[listID];
list.OnQuickLaunch = true;
list.Update();
}
}
}
}
}

Check if list is of the type Document Library or Not 

public bool CkechIfListisDocLib(SPList list) {
if (list is SPDocumentLibrary)
return true;
else
return false;
}

Running a Code with Elevated Permissions 

Use this in ur code. if u want to run a portion of the code with elevated permissions


SPSecurity.RunWithElevatedPrivileges(delegate()
{
// do something
});

Download a file from Document Library and Save it locally 

private static void DownloadAFile()
{
SPSite site = new SPSite("http://wwdevserver:3000/"); //site url

SPWeb web = site.OpenWeb(@"/Admin"); //web url

SPList list = web.Lists["PDF Form Templates"]; //list name



File.WriteAllBytes(@"c:\m.pdf", list.Items[0].File.OpenBinary()); //downloading first items file

}

SPWebConfigModification Class - Editing Sharepoint Web.Config 

I have seen some of the code where in if a "SafeControl" entry is need to be done in the web.config, through code, then we use
"XMLDocument" class to load the web.config and make changes . there is trouble in doing so as you need to manually get the path of the web.config and all.

But Sharepoint object model provides a class called "SPWebConfigModification" which can be used to play around with the web.config of the site.

Sample Code where in --Safe Control Entry is Made for the Webparts in the feature activation



public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPSite site = (SPSite)properties.Feature.Parent;

if (site != null)
{
SPWebApplication webApp = site.WebApplication;

SPWebConfigModification ModDesc = new SPWebConfigModification();
ModDesc.Path = "configuration/SharePoint/SafeControls";
ModDesc.Name = "SafeControl[@Assembly='Description'][@Namespace='Description'][@TypeName='*'][@Safe='True'] [@AllowRemoteDesigner='True']";
ModDesc.Sequence = 0;
ModDesc.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureChildNode;
ModDesc.Value = "";


webApp.WebConfigModifications.Add(ModDesc);

webApp.Farm.Services.GetValue().ApplyWebConfigModifications();
webApp.Update();

}

How to import data from AD to InfoPath 2007 Form Template

MOSS has a great new feature that allows (among other things) the publication of InfoPath forms to the server and thus enabling users that do not have InfoPath installed to fill in forms without having to distribute or purchase InfoPath for each client. 
One of the things everyone who has asked me about this have in common is that they all work in a Microsoft Active Directory environment and they all want their form to load Meta data from the current user and populate their form with that data.

Now, InfoPath and AD do not have a method for creating a direct connection, but since all of our users also utilize the Microsoft Office SharePoint Server (MOSS) forms server they can take advantage of other features and capabilities of MOSS to solve this problem. 
MOSS connects to your AD easily and builds a user profile based on the data stored in AD for each user. This part is easy enough to perform so I will not elaborate further on that here.

Once your MOSS “recognizes” your users, you can make use of its web services to retrieve all users list, a specific user profile and also the current user profile.

Here I will demonstrate how to create a form that loads current user profile data as stored in AD without writing a bit of code.

The only thing that needs to be done is to define a connection to a certain web service that already exists in your SharePoint site out-of-the-box (OOTB).

Step 1: Create a blank form template

1. Click file->design a form template 

2. Select “Blank” 
3. Click OK


Step 2: Setting up the web service connection
1. Create a new data source connection.
Go to tools –>Data connection 

2. In the "Data connections” dialog Click on Add 

3. Select create a new connection to - Receive data Click next 

4. Select Web service as the source type 

5. Insert the Following web service name: http:///_vti_bin/userprofileservice.asmx?wsdl 
6. Replace <servername> with your SharePoint server name and click next

7. From the operations drop down list selectGetUserProfileByName 

8. In MOSS, calling this operation without sending a user name will return current user’s profile.
9. Click "next" keeping the defaults in every screen until you can hitFinish



10. Close the Data connection window.

Step 3: Viewing and choosing the AD details we wish to import:
Now, we need to insert the AD information to the correct fields. To do so, we first need to see what kind of data we can use.

Since the users profile may include different properties according to your organizations' software and other dependencies, the web service results returns a set of “name-value” collection that we can use in order to get the results we need.
So – first, we have to find the “name” of the property and then we'll use it to get its value from the web service. 
Here is how it is done:
1. To see all the available fields click on View -> Data source 
2. In the Data source drop-down select the one we just created. 

3. Expand the DataFields container node and select the following fields in the results: 
4. In the drop-down menu on the selected nodes select "repeating table" and place it in the form.
5. You now have a repeating table with all data returned by the web service. To see all the AD fields available to you, Click "preview" in the tool bar. 
6. Now, locate the property you need and copy its name 
7. Return to the design mode by clicking "close preview".
Step 4: placing the AD details in the controls: 
Now the only thing left for us to do is place the field we chose earlier (in step 3) and define the control to show that field’s info.

1. In the form, double-click the control you wish to fill 
2. In the control properties click on to open the function editor


3. Then click on "Insert Field or Group". 

4. In the next window, select the data source you created 
5. Expand all the folders under "DataFields" until you can see and then select the "Value" node.
6. This inserts one of the “values” we got in the web service response. Now we need to enable it to “filter” the values by the property name we want. To do so:

7. Click on "Filter Data" button. In the pop up window click"Add
8. In the next window select the following options 
9. And select the “Name” node from our service data source: 

10. Click "Ok". Then Select "Type Text" and enter the property you copied in the previous section as the value 
11.Click "Ok" to confirm and close all the pop-ups.

12. Click "Preview" in the tool bar to see the results. 

Now your form displays the user preferred name as it was entered in the AD and all that without writing a single line of code!

Important: Your document must be fully trusted in order to execute the web service correctly. To do make sure they are, please check the"Tools-Forms Options" form security options.
This is a great demonstration how you can combine several Microsoft products to create excellent customer-specific solutions utilizing the out of the box features and capabilities, with no need for any extras!

Thursday, August 5, 2010

Building a Custom Workflow in Sharepoint Designer

The concept of workflow is not a new one and many commercial products on the market have been offering solutions for years, but at a very high cost. As most of you know by now, Microsoft was started working on this problem since the creation of the .NET framework 3.0 with the addition of WWF (Windows Workflow Foundation).
This has become the basis of workflow for most new Microsoft products like Office 2007, Project Server 2007, CRM 4.0 and MOSS 2007. Sharepoint specifically has many entry points into WWF and can basically be broken into the following levels of complexity:
  • Built-in or Downloaded workflow's - these come standard with Sharepoint or can be installed with add-on templates.
  • Sharepoint Designer - this tool allows you to customize many aspects of Sharepoint including custom workflow's.
  • Visual Studio 2005/2008 - this is the ultimate tool for building workflow's, but is quite often overkill for what is required.
The focus of this blog is to introduce you to the basic steps in building workflow's with Sharepoint Designer if you are not already familiar with it.
It all starts with an object and a content type. Workflow's need to be attached to object so that they know what they are interacting with and there are basically two types of objects in Sharepoint, a list or a document library. Content types define what metadata is stored with an object and is vital in building a useful workflow. Even the default object instances like "Contacts" or "Tasks" have content types associated by default. Therefore the basic steps required to build a workflow is the following:
  • Create an instance of an object like a "Document Library" in Sharepoint.
  • Define the meta data required and build it into a content type. Associate the content type with the object.
  • Build the workflow using SPD or VS and bind it to the object.
In the following example I will be building a custom workflow on a document library using Sharepoint Designer.
Start by creating a document library in a Sharepoint site and add some content to it.
Start Doc Lib
The next step would be to open an instance of SPD (Sharepoint Designer). Select "Open" from the file menu and point it to the site containing the document library.
Open Site SPD
To create a new workflow, select "New" --> Workflow from the file menu.
New Workflow
This action will initiated a wizard that will start up and guide you through the process.
Wizard 1 Welcome
A number of options are available to configure on this screen:
  • Name - each workflow requires and unique name to distinguish it from other workflow's in Sharepoint.
  • Bind Object - the workflow needs to be bind to and object that exists in the site that was opened in SPD.
  • Start Settings - the workflow is started by events triggered by the object. This can be "New" or "Edit" and is defined by the checkbox selections available.
  • Variables - custom variables can be created to store values that can be used throughout the steps that will follow. These can be used later in phase 2 of the wizard.
  • Initiation - it is possible to define questions that the user will be prompted with when the workflow is initialised. The responses can be used to determine the flow or outcome of the workflow.
Wizard 1 Ask Question
Once the initial options have been configured, select the "Next" button on the wizard to continue.
Wizard 2 Blank
The second phase of the wizard basically consists of an design pane that is used to create the logic of the workflow. Think of it as writing and "If Else If" statement in code, without actually having to write it yourself.
Also keep in mind that this is only the first step of logic in the workflow and additional steps can be created by selecting the "Add Workflow step" option on the right hand side of the screen.
Let's start by taking a look at the "Conditions" part of the logic first. This would map onto the "IF" part of a virtual script.
Wizard 2 Condition
When selection the drop down option called "Conditions" a number of options appear that allow you to define a condition for comparison to determine if this workflow should initialise or not. The workflow will always be invoked (Hydrated) when the events connected to he object fires, like "New" or "Edit", but the condition will determine if this particular workflow will be initialised.
These condition can range from comparing dates to specific file values connected to the document. This is were the importance of the content types come in. If you did not spend sufficient time initially to determine what meta data needs to be associated with a particular document and built this as a content type associated with the document, then at this particular point the workflow becomes difficult to build. I personally believe this is why many people believe that SPD is not sufficient to build workflow's in Sharepoint.
Keep in mind that specific values can be compared against each other by selecting the "Hyperlink" options that appear and then supplying either metadata fields or hard coded values for comparison. Additional branch logic can be created by selecting the "Else If" branch option further down the screen.
It is also possible to create "AND" and "OR" scenarios by selecting the "Condition" option more than once.
Now that the logic has been determined, it is time to decide what to do if the logic is "True" by setting the actions.
Wizard 2 Actions
To create an action for a particular condition is a simple matter of selecting the action from the drop down list called "Actions". In a similar fashion to the conditions, this will create "Hyperlink" options that can be configured by selecting them. Keep in mind that you always want to us metadata fields that come from the content type instance associated with this particular "Document" or "List Item" that invoked the workflow.
There are too many options to discuss them in detail and you will have to experiment and play with them to see what is available and how each of the options work. There are also a lot more options available by selecting the "More Actions" option from the drop down list as illustrated in the image below. Also keep in mind that some of the options only apply to lists and others only to documents.
For Example: When selecting the option called "Send and Email", do not hard code the email address by typing it into the action, but rather retrieve the email address from an meta data field associated with the content type. Assuming that you built it into the content type to start with.
It is also possible to add multiple actions to a condition by selecting the "Action" option more than once.
Wizard 2 More Actions
Once this step has been completed with its conditions and actions you need to determine if you need more steps. This was only the first step in the workflow and optionally more can be added by selecting the "Add Workflow step" on the right hand side of the screen.
When you have completed building the workflow, select the button called "Check Workflow" to determine whether your workflow will compile and the logic actually works. If you get the "All Clear", then select the "Finish button" to build the workflow.
XOML File
You will also notice that a new folder structure gets created in SPD called "Workflow's" that did not exists previously. This allows you to edit the custom workflow in future by editing the "xoml" file in the folder structure.
There is obviously a lot more that can be written about writing custom workflow's in SPD, but I hope this blog gives you enough of a starting point to start experimenting. There are some additional links below written by some other authors on this site relating to workflow's and Sharepoint

Wednesday, June 2, 2010

Windows Workflow: The Base Activity Library

The base activity library in Windows Workflow contains general-purpose activities for constructing workflows. There are activities for control flow, transaction management, local communication, web services, and more. These activities appear on the toolbox window of the workflow designer. Some of these activities, like the CodeActivity, are simple. The job of the CodeActivity is to execute a block of code. Other activities, like the PolicyActivity, are more complex. The PolicyActivity can evaluate prioritized rules with forward chaining. We can build powerful workflows using just the activities inside the base activity library.
We are about to embark on a tour of base activity library. Many of the activities here deserve a more thorough coverage, but our goal for this tour is to understand the basic capabilities of each activity type, and come away with an idea of when we can use each one. We will start he tour with the most basic activities.

The Basics

These activities model primitive operations that exist in almost every programming environment, like conditional branching, looping, and grouping of sub-activities. We will start with an activity that appears many times in these samples, the CodeActivity.

The Code Activity

The Code activity's only interesting feature is its ExecuteCode event. We will need to pair the event with an event handler before the activity will pass validation. In the workflow designer, we can double-click on a Code activity, and Visual Studio will create and assign the event handler for us - all we need to do is write the code. The following code is an event handler for ExecuteCode that displays a on the screen.

private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
  Console.WriteLine("Hello, World");
}
The CodeActivity Figure 1 shows the Code activity as it appears in the designer. A red exclamation point hovers above the top right of the activity because we have not assigned an ExecuteCode event handler, and the activity is failing validation. Anytime an exclamation point appears, we can click with the mouse to find the reason for the validation error.
It might seem useful to execute arbitrary code in a workflow, but in reality the Code activity should appear relatively infrequently and as a special case. Instead of using Code activities, we should look to package code into custom activities (a topic for the future). Custom activities can expose properties and allow us to turn arbitrary code into a reusable activity.
Also, many of the activities we will see later will raise events before, and sometimes after, anything interesting happens. We can use these event handlers to write small pieces of customized code for pre and post processing, instead of dropping a new Code activity into the workflow. We will see an example of these event handlers soon.

The IfElseActivity

The IfElse activity is similar to the If...Then...Else statement in Visual Basic, and the if-else in C#. Inside of an IfElse activity are one or more IfElseBranch activities. Each branch activity has a Condition property. We are required to set the condition property on all branches, except for the last branch.
The IfElseActivity The IfElse activity will execute the first branch whose condition property evaluates to true. If no conditions evaluate to true, then none of the branches will execute. The branches are evaluated from left to right. If the last branch has no condition, it will execute automatically if no other branches have run. We can add additional branches by right-clicking the IfElseActivity and selecting "Add Branch". We can remove branches by right-clicking a branch and selecting "Delete". Figure 2 shows an IfElse activity in action.
The Condition property of a branch can be either a declarative rule (which the designer persists to an external .rules file in XML format), or a code condition (an event handler). If we set the condition equal to Declarative Rule Condition, then we can launch the rule condition editor from the properties window and enter an expression. For instance, if the workflow has an integer property named Sales, we could enter an expression like the following.

this.Sales > 5000
The same condition written as a Code Condition would look like the following code.

private  void checkSalesAmount(object sender, ConditionalEventArgs e)
{
  e.Result = Sales > 5000;
}
The activity raises an event to evaluate a Code Condition. We can return the outcome of the condition as a true or false value in the event argument's Result property.

WhileActivity

Like the IfElse activity, the While activity has a Condition property which can be either a declarative rule or a code condition. The WhileActivity will continue to run as long as the condition returns true. This activity will evaluate the condition before each iteration (see Figure 3).
The WhileActivity Unlike the IfElseBranchActivity, the WhileActivity can hold only a single child activity inside. This restriction doesn't prevent us from using multiple activities inside of a loop, as we will see in the next section.

SequenceActivity

A Sequence activity is a composite activity, and can run one or more contained activities. The activities inside a sequence activity will execute one at a time, until the last activity completes. The WhileActivity only permits a single child activity, but if we make the single activity a SequenceActivity, we can drop additional activities inside the sequence activity. All of the children will then run each time the WhileActivity completes an iteration.

SuspendActivity

The Suspend activity will halt the execution of a workflow. A Suspend activity might be useful when a workflow encounters an error that requires manual intervention. The activity has an Error property, which is a string.
A host can subscribe to the workflow runtime's WorkflowSuspended event and retrieve the error message using the Error property of the WorkflowSuspendedEventArgs parameter. Another property of this parameter is the WorkflowInstance property. A host can recommence execution using the Resume method of the WorkflowInstance class, or bring about a sad, but early ending with the Terminate method.

TerminateActivity

Like the Suspend activity, the Terminate activity will halt the execution of a workflow. Unlike a suspended workflow, a host cannot resume a terminated workflow. We can use this activity if a workflow reaches a point where it cannot continue and has no hope of recovery.
The Terminate activity has an Error property of type string. A host can subscribe to the runtime's WorkflowTerminated event and examine the error. The event handler will receive a parameter of type WorkflowTerminatedEventArgs, and the runtime will wrap the error message into a WorkflowTerminatedException, which is available through the event argument's Exception property.
If we wanted a specific exception to arrive in the WorkflowTerminated event handler, we should use a Throw activity instead of a Terminate activity. However, there is a chance that the workflow can catch a thrown exception and continue, while the Terminate activity will always bring execution to a crashing halt.

ThrowActivity

The Throw activity is similar to the throw statements in C# and Visual Basic - the activity raises an exception. Why should we use a Throw activity when we could throw from the ExecuteCode event of a Code activity? Because using a Throw activity makes the exception an explicit piece of the workflow model.
If the exception goes unhandled and propagates out of the workflow, the WF runtime will catch the exception, terminate the workflow, and raise the WorkflowTerminated event. The runtime will also pass the thrown exception in the event arguments. The Fault property of the activity will reference the exception to throw. We can data-bind the Fault property to a field in our workflow, or to the property of another activity.
We can use the FaultType property to describe and restrict the exception types the activity will throw. If the FaultType is not set, the activity can throw any type of exception (as long as the type is System.Exception, or derived there from).

InvokeWorkflowActivity

The Invoke Workflow activity will asynchronously execute another workflow. Since the execution is asynchronous, we cannot retrieve output parameters from the other workflow, although we could setup additional communication mechanisms with the host to make the output available.
In the designer, we set the TargetWorkflow property to reference the workflow type we wish to execute. We can choose from workflow types defined in the same project, or in a referenced assembly. Once we've set the target, the designer will allow us to setup parameter bindings by looking at the public properties of the target type. We can bind fields and properties of our workflow as parameters for the target workflow. Before starting the second workflow, this activity will fire an Invoking event. We can use code inside the Invoking event handler to tweak and initialize the parameters.

ParallelActivity

The Parallel activity allows multiple activities to execute at the same time. This does not mean the Parallel activity permits parallel processing across multiple threads - only a single thread will execute inside of a workflow. Instead, the Parallel activity allows separate branches inside the activity to execute independently.
As an example, let's pretend we are writing a workflow that requires a yes or no vote from three members of our company: the chief executive officer (CEO), the chief technology officer (CTO), and the chief financial officer (CFO). The host will deliver the votes to the workflow as events.
We could write the workflow so that it would wait for the votes to arrive sequentially - first the CEO, then the CTO, then the CFO. This means the CTO couldn't vote until the CEO cast a vote, and the CFO couldn't vote until the CTO cast a vote. If the CTO is away for a few days and can't vote, the CFO will have to wait. A word of advice from the author - making a CFO unhappy does not increase your chances of career advancement at the company.
The ParallelActivity If the order of the votes is not important, it would make more sense to let the software collect the votes as they arrive - in any order. The parallel activity in figure 4 4 will listen for three events simultaneously. Whichever officer votes first, the workflow will process the event and then wait for the other two events to arrive. The parallel activity will not finish until all three events have arrived.

DelayActivity

The Delay activity will initialize a timer and wait asynchronously for the timer to expire. The TimeoutDuration property contains the TimeSpan that represents the amount of time to wait. We can initialize the property in the designer, or programmatically by assigning an event handler for the InitializeTimeoutDuration, shown below.

private void delayActivity1_InitializeTimeoutDuration(object sender, EventArgs e)
{
    // a 5 second timeout    this.delayActivity1.TimeoutDuration = newTimeSpan(0,0,5);
}
We often find a Delay activity inside of a Listen activity.

ListenActivity

Like the Parallel activity, the Listen activity can contain multiple branches. Unlike the Parallel activity, the goal of a Listen activity is to finish just one branch. The branches of a Listen activity are Event Driven activities, and we must start the branches by waiting for an event (the first child must implement the IEventActivity interface). We'll see the Event driven activity in more detail when we cover state machine workflows.
Let's go back to our previous workflow example with the CEO, the CTO, and the CFO. Previously we needed a vote from all three officers before the workflow could continue. If we only needed a vote from one of the three officers, the Listen activity would be a better fit. When one of the events arrives, the activity will execute the branch associated with the event and cancel the execution of the other branches.
The ListenActivity As alluded to earlier, we can use a Delay activity inside of a Listen activity and simulate a timeout. This arrangement is shown in figure 5. If the delay timer expires before any of the other events arrive, we can take an alternative action, perhaps by emailing a reminders to vote, or moving ahead with a default choice. Silence is consent!

EventHandlingScopeActivity

The Event Handling Scope activity is similar to a Listen activity in that it can have multiple branches waiting for events in parallel. We can view these branches by right-clicking the activity and selecting "View Events". The primary difference between this activity and a Listen activity is that this event continues to listen for all events until its main child activity (the default view) finishes execution.
Imagine we are setting up a workflow that will count employee votes over a period of 30 minutes. We could set the main child activity of the Event Handling Scope activity as a Delay activity, with a 30-minute timeout. We can then place event handling activities in the event branches that listen for Yes and No votes. This activity will continues to listen for the Yes and No events until the Delay activity completes in 30 minutes.

SynchronizationScopeActivity

Like the threading synchronization primitives in the .NET libraries, the Synchronization Scope activity can serialize access to shared resources, even across workflow instances. If we have a static (C#) or shared (Visual Basic) field in our workflow definition, the Synchronization Scope can ensure only a single instance will have read and write access to the field.
The SynchrnoizationHandles property contains the handles that the workflow will acquire before it executes, and release upon completion. A synchronization handle is a simple string object, and the property maintains a collection of strings. Internally, the WF runtime will use each string as the key to a Dictionary of locks. If the activity cannot acquire all the locks specified by the handles, it will wait until it can acquire the locks.

ReplicatorActivity

The Replicator activity is similar to the While activity, but more sophisticated. The Replicator can process a collection of data either sequentially or in parallel, depending on the setting of the ExecutionType property.
Think back to the example we talked about for the Parallel activity. We needed a vote from exactly three officers of the company before the workflow could proceed. The Replicator is a better fit when we don't know how many events we need to process until runtime. Perhaps a user is checking off the required voters from a company wide directory. A Replicator can create the required number of event listeners we need from the list of voters.
The InitialChildData property will hold the list of data objects for the Replicator to process. The Replicator will create a clone of its child activity to process each item. The Replicator will not finish execution until all the children have finished, however, there is an UntilCondition property that the Replicator will evaluate before starting, and after completion of each child. If the UntilCondition returns true, the Replicator will finish execution, even if it leaves children unprocessed. Like other conditions in WF, the UntilCondition can be a rule condition or a code condition.
The Replicator fires a number of useful events, including Initialized, Completed, ChildInitialized, and ChildCompleted. The ChildInitialized event is a good time to populate the cloned child activity with the data it needs to execute.

Local Communication Events

When it comes time for a workflow to communicate with the outside world, there are a handful of built-in activities to do the job. The activities we discuss in this section will communicate with local services provided by the hosting process.
For local communication to work, we need to define a contract in the form of a .NET interface. The interface will define the methods that a workflow can invoke on a local service, and the events that a local service can raise to a workflow.
Let's say we are working on a workflow for a bug tracking system. At some point, a bug might need detailed information, like a screen shot, uploaded to the application. If the workflow needs this additional documentation, the workflow can ask the host to upload the document. The host might upload the documents itself, but more than likely it will notify a user that the bug requires more information. In either case, the workflow will have to wait (perhaps a few seconds, perhaps a few days or longer), for the uploaded document to arrive. The host can let the workflow know when the upload is complete via an event. The following interface defines the communication contract we need to enable this scenario:

[ExternalDataExchange]interfaceIBugService{    bool RequestUpload(Guid id, string userName);    event EventHandler<UploadCompletedEventArgs> UploadCompleted;
}
The two activities to interact with the interface are the CallExternalMethodActivity and HandleExternalEventActivity.

CallExternalMethodActivity

The CallExternalMethodActivity The Call External Method activity invokes a method on a local service. All we need to do is setup the properties of the activity, as shown in figure 6.
The InterfaceType property should be set first, as this will allow the designer to discover the available methods on the service. Once we set InterfaceType to the interface we defined, we can select the method to call in the MethodName property. The designer will then populate the Parameters area of the property window. We can bind all the input parameters, and the method return value, to fields and properties in our workflow. The uploadRequested, id, and userName fields are all member variables in the code-behind class of our workflow.
For the Call External Method activity to work, we will need to add the ExternalDataExchangeService to the workflow runtime, and add a service that implements our interface to the data exchange service, as shown in the code below. The BugFlowService class implements the IBugService interface.

ExternalDataExchangeService dataService = newExternalDataExchangeService();
workflowRuntime.AddService(dataService);
BugFlowService bugService = new BugFlowService();
dataService.AddService(bugService);
The Call External Method activity includes a MethodInvoking event. The event will fire just before the activity calls the external method, and gives us an opportunity to setup the parameters. We might add code like the following to the event.

private void callExternalMethodActivity1_MethodInvoking(  object sender, EventArgs e)
{
  id =
this.WorkflowInstanceId;
  userName =
"Scott";
}

HandleExternalEventActivity

The HandleExternalEventActivity The Handle External Event activity, like the Call External Method activity, has an InterfaceType property we must set. Once we have set this property we can set the EventName property (see figure 7).
Handle External Event is a blocking activity, meaning the workflow is not going to proceed until the event arrives from a local service. If there is a chance the event will never arrive, or if the event needs to arrive within a span of time, then it's best to use this activity inside of a ListenActivity. As we described earlier, the Listen activity has multiple branches, and we can place a DelayActivity in one of the branches to simulate a timeout.

The Activity Generator

The Windows Workflow SDK includes a command line tool called the Windows Workflow Communications activity generator. This tool runs from the command line, and you can find it in the SDK directory with a name of wca.exe.
We can pass wca.exe the path to a .NET assembly (.dll) and the tool will look through the assembly for interfaces decorated with the ExternalDataExchange attribute. When the tool finds such an interface it will generate dedicated activities for calling the methods and handling the events of the interface.
For our IBugService interface, the tool will generate a RequestUploadActivity and an UploadCompletedActivity. The tool generates the activities as source code files that we can include in our project. The activities will have their InterfaceType and EventName or MethodName properties pre-populated, and include properties for all parameters in the communications.
Run wca.exe with no parameters to see a list of options.

Roles

The Roles property of this activity can bind to a WorkflowRoleCollection object and allow the runtime to perform role-based authorization checks. The runtime compares the role memberships of the incoming identity against the allowable roles defined in the collection. The collection holds objects derived from the abstract WorkflowRole class. WF provides two concrete implementations of WorkflowRole with the ActiveDirectoryRole and WebWorkflowRole classes. These classes work with Active Directory and ASP.NET 2.0 Role Providers, respectively. If authorization fails, the runtime will throw a WorkflowAuthorizationException exception.

Fault Handling

Although fault handling is arguably a type of control flow, this section is dedicated to these activities so we can dive in with more detail. Fault handling in Windows Workflow handles exceptions that occur during execution. We can catch exceptions with fault handlers, and perhaps try to recover from the error. We might try to compensate for a committed transaction, or send an alert to an administrative email address and wait for a missing file to reappear.
It is always a bad idea to blindly handle faults if we don't have a recovery plan. This is akin to swallowing exceptions in C# or Visual Basic. If the workflow throws an exception that we don't know how to handle, it is best to let the exception run its course and have the runtime terminate the workflow.

FaultHandlersActivity

The Fault Handlers activity isn't an activity we can drag from the Toolbox into the workflow designer. Instead, the workflow designer will provide the activity for us when the condition is right. Many composite activities (like the WhileActivity, ListenActivity, SequenceActivity, TransactionScopeActivity, and others) can handle faults from their child activities using a fault handlers view
Workflow Fault Handlers We can view the Fault Handlers activity by right clicking an activity and selecting "View Faults". There is also a shortcut available to view fault handlers at the workflow level. The third tab from the left in the bottom of the workflow designer will take us to the fault handlers for the workflow (see figure 8). Inside of this view we can use Fault Handler activities, discussed next.

FaultHandlerActivity

A Fault Handler activity is analogous to a catch statement in C# or Visual Basic. The activity can trap an exception and perform some processing. When we are in the Fault Handlers view, we can drag a Fault Handler from the toolbox into the area saying "Drop FaultHandlerActivity Here". This area is the Fault Handlers storyboard. We can drop more than one Fault Handler into the storyboard, and click on the different handlers inside to select the handler we want to edit. Each handler has its own set of child activities that appear below the storyboard. We can drop activities in this area below the storyboard to perform different types of work for each fault handler. This is akin to the code inside of a catch block.
The FaultHandlerActivity has a FaultType property. This property represents the type of exception we want to catch. If we set the FaultType property to the System.Exception type, we will handle all CLS compliant exceptions. The handler will catch all exceptions of type FaultType, or any exception deriving from FaultType. The Fault property of this activity will let us bind the caught exception to a field or property.
The runtime will evaluate Fault Handlers in a left-to-right order. If the first Fault Handler has a FaultType of System.Exception, it will catch any exception and the runtime won't need to evaluate the other fault handlers. This is similar to how the multiple catch statements work in C# or Visual Basic - the catch blocks are evaluated in the order they appear until a match is found, and then no other catch statements are evaluated.

Transactions and Compensation

Traditional ACID transactions (atomic, consistent, isolated, and durable) are available in Windows Workflow. Under the covers, the runtime makes use of the Transaction class in the System.Transactions namespace. The Transaction class can manage transactions across different types of durable stores, including Microsoft SQL Server and other relational databases, and products like Microsoft Message Queuing. The Transaction class can make use of the Microsoft Distributed Transaction Coordinator (MSDTC) for heavy-weight two phase commit transactions, when needed.

TransactionScopeActivity

TransactionScope Activity Like the TransactionScope class of System.Transactions, the Transaction Scope activity will begin a new transaction and implicitly enlist the activities it contains into the transaction. The TransactionOptions property controls the timeout and the isolation level of the transaction (see figure 9).
If the Transaction Scope activity finishes with no errors it will automatically commit the transaction. If an exception occurs inside the scope and is not caught by a fault handler inside the scope, the activity will abort the transaction and rollback any work.

CompensateActivity

In a long running workflow, we can't leave a transaction open for hours, or days, or weeks at a time. What we will typically do is commit the transaction as soon as possible and move on with execution. At some later point, however, if an error might occurs, we might need to reverse the work we committed inside the transaction. The Compensate activity is designed to take care of reversing transactions.
Compensate Activity Before we can make effective use of a Compensate activity, we need to look at the Compensation Handler activity for a transaction. A Compensation Handler activity contains the activities the runtime will execute to reverse a transaction. We can add the compensating activities by right-clicking a Transaction Scope activity and selecting "View Compensation" from the context menu. Figure 10 shows an empty Compensation Handler activity for a Transaction Scope activity.
Any activity implementing the ICompensatableActivity can have an associated Compensation Handler activity. In the WF Base Activity Library, only the Transaction Scope activity implements this interface, but we can write custom activities with the interface.
Once we have activities inside of the Compensation Handler activity, we can trigger compensation with the Compensate activity. The Compensate activity's TargetActivityName property will direct the workflow to the ICompensatableActivity that needs reversed. The runtime will then execute the activities inside the Compensation Handler activity.
We can only place Compensate activities inside of Compensation Handlers and Fault Handlers. Inside the Compensation Handler of a Transaction Scope activity, the Compensate activity can direct the reversal of other nested transactions. Inside a Fault Handler, the Compensate activity can direct the reversal of any in-scope transaction.

Conditions and Rules

Two activities in Windows Workflow thrive on conditions and rules. These activities are the Policy Activity and the Conditioned Activity Group (CAG). Although we could have listed the CAG as a control flow element, the CAG doesn't control the flow of execution as much as it is controlled by conditions and rules.

ConditionedActivityGroup

The CAG The CAG is a powerful activity that can use a combination of rules and code to reach a goal. The CAG conditionally executes activities until a condition evaluates to true. Inside of the CAG is a storyboard where we can drop activities for execution (see figure 11). The CAG associates a WhenCondition with each activity, and the CAG will only execute an activity if the activity's WhenCondition evaluates to true. The CAG continues to re-evaluate the WhenCondition and re-execute the storyboard activities until its own UntilCondition evaluates to true.
The WhenCondition and UntilCondition properties can use either declarative rules or code conditions. If we do not specify a WhenCondition for an activity, the activity will execute only once. If we do not specify an UntilCondition for the CAG, the CAG will continue to execute until all its activity's WhenCondition conditions return false.
We can click on each activity in the CAG's storyboard to set its WhenCondition, and also to preview or edit the activity in the bottom half of the CAG display. The small button in the middle of the CAG will toggle between preview and edit modes. In edit mode we can click on the activity to set properties, or in the case of a composite activity like the Sequence activity, we can drag additional children inside.
The CAG will revaluate its UntilCondition each time a child activity completes. As soon as the condition returns true the CAG will cancel any currently executing activities and close.

PolicyActivity

The PolicyActivity The Policy activity is a rules engine that allows us to separate business logic from the workflow and declaratively define a business policy. Rules are everywhere in the business world - from calculating loan approvals to admitting patients into a hospital. A Rule Set is a collection of rules for the Policy activity to execute, and each rule has conditions and actions. We can edit the rules using the WF Rule Set editor, shown in figure 12.
Notice each rule has a priority assigned. Rules with a higher priority will execute before rules with a lower priority. Each rule has an If-Then-Else format, and we can assign actions to both the Then and Else results. A rule's actions can modify the fields and properties of a workflow, or the fields and properties of an object inside the workflow. Actions can also invoke methods.
By default, the Policy activity will execute the rule set using full forward chaining. If a rule changes the value of a field that some previous rule depended upon, the Policy activity will re-evaluate the previous rule. The Policy activity supports different forward chaining strategies, and each rule has a re-evaluation setting to control the number of times it can be re-evaluated.

Web Services

No product would be complete today if it did not send or receive SOAP envelopes over HTTP. WF includes a number of activities that revolve around web services, both as a consumer and a producer.

InvokeWebServiceActivity

The InvokeWebServiceActivity The Invoke Web Service activity can call an external web service. When we drop the activity into the workflow designer, the familiar Visual Studio Add Web Reference dialog box will appear. This same dialog appears when we add a web reference to any type of .NET project in Visual Studio. We merely need to browse to the Web Service Definition Language (WSDL) description of the web service. Visual Studio will retrieve the WSDL and generate a proxy class for the service. We then configure the activity with the method name to invoke, and bind parameters to field or properties in our workflow (see figure 13).
The Web Service Activity includes Invoking and Invoked event handlers that fire before and after the web service call, respectively. We can use these events to pre and post process the parameters of the web service.

WebServiceInputActivity

The Web Service Input activity enables a workflow to receive a web service request. Just like the local communication activities we described earlier, this activity will first require us to define a contract (an interface). The activity will implement the interface. Once we've set the InterfaceType property, we can pick a method from the interface for the MethodName property, and then bind the incoming parameters to fields or properties.
Visual Studio 2005 allows us to right-click a workflow project and select "Publish As Web Service". This command creates an ASP.NET project, complete with .asmx and web.config files, that will host our workflow as a web service.

WebServiceOutputActivity

A Web Service Output activity pairs with a Web Service Input activity to respond to a service request. We cannot use this activity without first configuring a Web Service Input activity in our workflow. This activity has an InputActivityName property that will pair the activity with it's input. The designer will then know the interface and method name we are implementing, and allow us to bind the ReturnValue property. The ReturnValue property is the web service response.

WebServiceFaultActivity

The Web Service Fault activity allows us to raise an exception that the runtime will package into a SOAP exception. Like the output activity we just described, the Web Service Fault activity will pair with an input activity via the InputActivityName property. The Fault property will reference the exception we want to raise.

State Activities

All of the workflows we've examined so far have been sequential workflows. Windows Workflow also supports state machine workflows, which is where the activities in this section come into play.
A state machine consists of a set of states. For instance, a state machine to model the workflow of a software bug might include the states open, assigned, closed, and deferred. The workflow must always be in one of these four states. State machines are completely event driven. Only when the workflow receives an event can the current state transition to a new state. A state machine must have an initial state, and optionally an ending state. When the state machine transitions to the ending state, the workflow is complete.
State machine workflows are a good fit for modeling a process where decisions come from outside the workflow. When we make a decision, like closing a bug, we have a local communication service raise an event to the workflow. The workflow keeps track of which state it is in, and which states it can transition into from the current state. For instance, we might say that an open bug has to be assigned before it can be closed, but it can move from the open state directly to the deferred state. The first step in setting up a state machine is defining the states.

StateActivity

The State activity represents one of the states in a state machine. For our bug tracking workflow, we would have four State activities to drop into the designer - one for open, closed, deferred, and assigned. Unlike a sequential workflow, we can place these activities anywhere on the design surface, because the state machine doesn't move from one activity to the next in any specific order. We will need to define the legal state transitions.
The StateActivity Every state machine workflow needs an initial state. We can set the initial state using the InitialStateName property of the workflow itself (see figure 14). We can optionally set the CompletedStateName to a state that represents completion of the workflow. The state machine in figure 14 has the four State activities for bug tracking: OpenState, AssignedState, DeferredState, and ClosedState.
Inside of each state, we can place the activities described below. Notice we can include a State activity inside of a State activity. The recursive composition of states allows contained states to inherit the events and behavior of their containing state.

StateInitializationActivity

The StateInitializationActivity The State Initialization activity is a sequence activity that contains child activities. When the state machine transitions to a state, the children inside the initialization activity will execute. We can only have one initialization activity per state. Once we've dropped this activity inside of a state, we can double click to edit the children. In figure 15, we've added an initialize activity to OpenState, and can now add child activities of any type as children.

StateFinalizationActivity

Like the initialize activity, the State Finalization activity is a sequence activity with child activities inside. When the state machine transitions out of a state, the state's finalization activities will execute. There can be only one finalization activity inside of each state.

EventDrivenActivity

The Event Driven activity is also a sequence activity with children inside. The Event Driven activity, however, only executes when an event arrives. The first child activity must implement the IEventActivity interface, like the Handle External Event activity. You might remember we described this activity briefly when we discussed the ListenActivity.
A State activity can contain more then one Event Driven activity inside. For example, our OpenState state will have two Event Driven activities inside - one to handle a BugAssigned event, and one to handle a BugDeferred event. We do not allow the OpenState to handle a BugClosed event, because we don't want to transition from open to closed without going through the assigned state.
The EventDrivenActivity In figure 16, we've double-clicked on an Event Driven activity in OpenState to configure an event handler for the BugAssigned event. The event is part of a communication interface we've built with the ExternalDataExchange attribute, just as we did earlier in the section covering the Handle External Event activity. Notice the last activity inside the sequence is a SetState activity, which we cover next.

SetStateActivity

The SetState activity transitions a state machine to a new state. In figure 16, we are handling the BugAssigned event. When a bug is assigned, we want to transition to the AssignedState, so we set the TargetStateName property to AssignedState. The AssignedState activity will then have it's own set of Event Driven activities, each with SetState activities to transition to other states (and hopefully one day reach the ClosedState).
The State Machine desginer The workflow view of a state machine will use examine the possible state transitions and draw lines to represent state transitions. In figure 17, we can see that state machine will only transition to the ClosedState activity from the AssignedState activity. We also see lines representing all the other state transitions.