In this article we can explore using multiple activities in a Site Workflow created using Visual Studio 2010. The core activities we use here are:
- Code Activity to execute custom code
- While Activity to execute inner activities upon condition is true
- IfElse Activity to execute branching activities based on condition
- LogToHistoryList Activity to log information to Workflow internal history list
Scenario
A typical approval scenario is being addressed here. An Expenses list is given for approval. The entries having an amount lesser than 100 are approved.
Pre-Requisites
Create a custom list named Expenses for using this example. Add some items into the new list as shown below:
Create Workflow
Open Visual Studio 2010 and create a new Sequential Workflow Project as shown below:
In the next page choose your site collection and click the Next button to continue.
In the page that appears choose Site Workflow as shown below:
In the last page choose the option to start the workflow manually.
Now you will be getting the Workflow designer with default activity inside it.
Add Activities
Open Visual Studio. Now you can drag and drop the following activities from the Toolbox:
- 1 Code Activity
- 1 While Activity & IfBranch Activity
- 2 Code Activity inside If, Else branches
- 1 LogToHistory Activity
As shown below:
Our idea is the following:
- Create a property named CurrentItem of type object, Index of type integer
- In the first Workflow activated, fetch all the Expenses items
- In the Code Activity initialize the Index field
- Set the While Activity condition until CurrentItem is not null
- Set the If branch condition as Amount less than 100
- Set the Else branch condition as Amount greater than or equal to 100
- Set the Code Activity in an If branch, to update the status as Approved
- Set the Code Activity in an Else branch, to update status as Rejected
- Use the LogToHistory activity for logging the workflow completion information
Create Entity, Properties & Fields
Please create the following class to hold the Expense Item, to give an Object Oriented look and feel.
namespace ExpenseApprovalWorkflow
{
public class ExpenseItem
{
public int ID;
public double Amount;
}
}
Inside the Workflow class, add the following properties and fields.
namespace ExpenseApprovalWorkflow.Workflow1
{
public sealed partial class Workflow1 : SequentialWorkflowActivity
{
List<ExpenseItem> Expenses = new List<ExpenseItem>();
int Index;
ExpenseItem CurrentItem
{
get
{
if (Index < Expenses.Count)
return Expenses[Index];
return null;
}
}
}
}
The Expenses list holds the ExpenseItem type items. The Index property represents the current index of the item being processed.
Initiation Code
Back to the workflow designer, double-click on the onWorkflowActivated step and add the following code:
private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
{
using (SPSite site = SPContext.Current.Site)
{
using (SPWeb web = site.OpenWeb())
{
var items = web.Lists["Expenses"].GetItems("ID", "Amount");
foreach (SPListItem item in items)
{
ExpenseItem expenseItem = new ExpenseItem();
expenseItem.ID = (int)item["ID"];
expenseItem.Amount = (double)item["Amount"];
Expenses.Add(expenseItem);
}
}
}
}
The code fetches all Expenses list items from SharePoint and adds them to the Expenses field of our workflow class.
Code Activity
Double-click on the Code Activity item from the Workflow Design View (second activity). In the code window that appears enter the following code:
private void codeActivity1_ExecuteCode(object sender, EventArgs e)
{
Index = -1;
}
The code initializes the Index field to -1. This field will be incremented in the while loop later.
While Activity
Now select the While activity from the workflow design view and choose the Properties window. Choose the Condition property as Code Condition and set the Inner Condition property as WhileCodeCondition.
The WhileCodeCondition represents the name of the method which evaluates the While condition and returns true or false to continue or terminate the workflow.
Paste the following code in the Workflow class view.
private void WhileCodeCondition(object sender, ConditionalEventArgs e)
{
Index++;
e.Result = (CurrentItem != null);
}
You can see the method name matches the property we have specified. The method receives the ConditionalEventArgs for specifying the condition for the while activity.
IfElse Activity
You can see that there are 2 branch activities for the IfElse activity.
Select the first branch item and open the Properties window. Here we can specify the following properties:
-
Condition as Declarative Rule Condition
-
ConditionName as IfCondition
-
Expression as this.CurrentItem.Amount < 100
You can see them in the Properties window as shown below:
The ellipsis button as highlighted in red color can be used to create the Expression. There is an auto-completion enabled in the editor dialog that appears.
Now select the second branch item and open the Properties window. Here we can specify the following properties:
-
Condition as Declarative Rule Condition
-
ConditionName as ElseCondition
-
Expression as this.CurrentItem.Amount >= 100
Now our If and Else branches are ready to proceed with their Code activities.
Code Activity for If branch
Now double-click on the Code Activity for the If branch.
In the code view that appears, enter the following code:
private void codeActivity2_ExecuteCode(object sender, EventArgs e)
{
using (SPSite site = SPContext.Current.Site)
{
using (SPWeb web = site.OpenWeb())
{
var item = web.Lists["Expenses"].GetItemById(CurrentItem.ID);
item["Status"] = "Approved";
item.Update();
}
}
}
The code fetches the Expense Item by ID and updates the Status as Approved.
Code Activity for Else branch
Now double-click on the Code Activity for the Else branch.
In the code view that appears, enter the following code:
private void codeActivity3_ExecuteCode(object sender, EventArgs e)
{
using (SPSite site = SPContext.Current.Site)
{
using (SPWeb web = site.OpenWeb())
{
var item = web.Lists["Expenses"].GetItemById(CurrentItem.ID);
item["Status"] = "Rejected";
item.Update();
}
}
}
The code fetches the Expense Item by ID and updates the Status as Rejected.
LogToHistoryList Activity
This activity logs information into the History List of the site. Select the activity and set the following property:
This list is a hidden list and is not shown in the Quick Launch or All Site Content.
To view the list you need to type the List Name in the address bar. For example:
http://SERVER/Lists/workflow%20history/AllItems.aspx
You can see various entries in the History List as shown below:
Using the History List we can verify the workflow instances being executed and their log information for troubleshooting.
Deploy the Workflow
Now we are ready to execute our workflow. Build the project, right-click on the solution and Deploy it.
Inside SharePoint
Back in SharePoint choose the Site Workflows and start our workflow.
Wait for a while for the execution to be completed.
Back to the Expenses list you can see the Status column being updated for the items.
You can open the Workflow History list to view the log entry as shown below:
This concludes our playing with Workflow activities.
References
http://msdn.microsoft.com/en-us/library/ms446847.aspx
Summary
In this article we have explored creating a Site Workflow using multiple activities. To summarize, the following are the activities we have explored:
I hope this example should provide knowledge to address complex workflow challenges in your programming life. The source code contains the example we have discussed.