我们知道,SharePoint的工作流是通过任务来驱动的,在真实场景中,我们可能会希望工作流的任务处理方式能够更加灵活,比如批量处理、通过Office Communicator等IM软件处理任务等等,这时候我们就需要以编程的方式在外部完成任务。
按照正常的想法,SharePoint的任务列表也是一个SPList,所以我们会这样尝试:
SPSite site = new SPSite( "http://windstyle" ); |
SPWeb web = site.OpenWeb(); |
web.AllowUnsafeUpdates = true ; |
SPList taskList = web.Lists[ "任务" ]; |
SPListItem task = taskList.Items[0]; |
task[ "Completed" ] = true ; |
web.AllowUnsafeUpdates = false ; |
执行之后,发现任务确实已经被设置为已完成状态,但工作流却没有继续执行,也就是说,工作流的OnTaskChanged活动并没有捕捉到任务被更改的事件。
其实SharePoint对象模型提供了更改工作流任务属性的方法,即SPWorkflowTask.AlterTask,此方法不仅能够更改工作流任务的属性,还会将这一更改通知相应的工作流,使得相应的工作流能够继续执行。
此方法的用法也很简单:
SPSite site = new SPSite( "http://windstyle" ); |
SPWeb web = site.OpenWeb(); |
SPList doclib = web.Lists[ "共享文档" ]; |
SPListItem doc = doclib.Items[0]; |
SPWorkflowTaskCollection tasks = doc.Workflows[doc.Workflows.Count-1].Tasks; |
Hashtable ht = new Hashtable(); |
ht.Add(SPBuiltInFieldId.FormData, SPWorkflowStatus.Completed); |
ht.Add(SPBuiltInFieldId.Completed, true ); |
ht.Add(SPBuiltInFieldId.TaskStatus, "已完成" ); |
ht.Add(SPBuiltInFieldId.PercentComplete, 1); |
ht.Add(SPBuiltInFieldId.WorkflowOutcome, "Some output infomation" ); |
SPWorkflowTask.AlterTask(tasks[0], ht, true ); |
从上段代码可以看出,以编程的方式来完成任务并不困难,其中比较麻烦的是如何找到正确的工作流任务。因为SPListItem.Workflows可能包含不止一个SPWorkflow,这些 SPWorkflow可能源于同一个SPWorkflowTemplate,也可能源于不同的SPWorkflowTemplate。而且还可能包含源于同一个SPWorkflowTemplate的多个SPWorkflow,当然,我们知道,同一个工作流模板在同一个SPListItem上只能启动一个工作流实例,所以这些SPWorkflow中只有一个的IsCompleted属性为true。
所以在编写代码来完成工作流任务时,注意获取到正确的工作流任务,然后就可以轻松的完成任务了。
来源:http://coding.windstyle.cn/2009/05/11/sharepoint-workflow-development-tips-7-completing-task-using-code/