SharePoint workflows can use OnWorkflowItemChanged and OnWorkflowItemDeleted activities to capture the "changed" and "deleted" events for the list items associated with the SharePoint workflow instances. To capture the "changed" and "deleted" events for the list items not associated with SharePoint workflow instances, we need to use SharePoint workflows' IListItemService.
IListItemService is one of four ExternalDataExchange services - IListItemService, ISharPointService, ITaskService and IWorkflowModificationService - registered by SharePoint runtime. IListItemService provides the methods and events to handle any list items in the SharePoint Site Collection where a workflow instance is running. To study the interface, I developed two workflows to illustrate two different scenarios using IListItemService.
Scenario 1: A workflow needs to capture the OnItemChanged event of a pre-existing list item.
To test the scenario, I created two SharePoint lists:
- workflowlist: it has a workflow association with the testing workflow and one item called "workflow item".
- anotherlist: the changed events of its items should be captured by the testing workflow associated with workflowlist above. The list's listid is 7c455073-56ce-4ecd-bfa8-2923fc521b9e and it has one item called "another list item". The id of the item is 1.
The following is the design view of the testing workflow:
The workflow includes three activities:
1. OnWorkflowActivated activity is required by all the SharePoint workflows.
2. InvokeIntializeForEvent is a subclass of CallExternalMethodActivity with the following parameters:
The activity will invoke the InitializeForEvent method defined in the IListItemService interface. The signature of the method is:
[CorrelationParameter("id"), CorrelationParameter("itemId"), CorrelationParameter("listId"), ExternalDataExchange, SharePointPermission(SecurityAction.LinkDemand, ObjectModel=true), SharePointPermission(SecurityAction.InheritanceDemand, ObjectModel=true)]
public interface IListItemService
{
......
void InitializeForEvent(Guid id, Guid listId, int itemId);
}
|
3. handeItemChangedEvent is a HandleExternalEvent activity with the following parameters:
This activity will wait on the OnItemChanged event defined in IListItemService interface. It should use the same Correlation Token, newtoken, for the activity prior to it.
We can test the workflow with the following steps:
1. Start the workflow for the "workflow item” list item in the "workflowlist" SharePoint list. The workflow should stop at "in progress" status since it is blocked and waiting for the OnItemChanged event.
2. Modify the "another list item" list item in the "anotherlist" list and change its title to "another list item changed".
3. Go back to the workflow list. Its workflow status is changed to complete since step 2 modifies the list item and trigger OnItemChanged event.
The solution demonstrates the following key points:
- IListItemService.InitializeForEvent should be invoked to establish the correlation token for a list item before you can capture the event for the list item. (You may use IListItemService.UpdateListItem, CheckInListItem, etc instead. ).
- listId and itemId for InitializeForEvent must match the ids of the SharePoint list and list item.
- id for InitalizeForEvent can be any uniquely generated GUID. It does not need to match any ids.
Scenario 2: A workflow needs to create an new list item and wait on its changed events.
In this case, you need to use IListItemSevice.CreateListItem to create the list. However, you cannot use the correlation token for CreateListItem because the "itemId" parameter is unknown while invoking the method. You can get the itemId as a "returnvalue" in your workflow instead.
So, here is the solution:
1. Add a CallExternalMethod activity to invoke the "CreateListItem" method. The activity should include an event handler for MethodInvokded event. In the event handler, get the return value and assign the value to a member variable to the workflow.
protected override void OnMethodInvoked(EventArgs e)
{
this.ItemId = (int)base.ParameterBindings["(ReturnValue)"].Value;
}
2. Add an InitializeForEevnt activity to invoke the "InitializeForEvent" method. Make sure use the ItemId returned by CreateListItem. This activity should create a new token, which is different from the one for "CreateListItem". The token for "CreateListItem" is basically not used any where.
3. Add an HandleExteranlEvent activity as in Scenario 1.
No comments:
Post a Comment