现在的位置: 首页 > 综合 > 正文

【Moss开发系列】WF+Aspx进行Moss工作流开发(3)

2012年07月07日 ⁄ 综合 ⁄ 共 6991字 ⁄ 字号 评论关闭

      上文中,使用Aspx内容类型+ascx用户控件的方式,实现了task1,task2表单的关联与动态加载,实现了与WF+InfoPath同样的效果,也达到了最初用Aspx表单替代InfoPath表单的目的,然而又一问题摆在我们面前,InfoPath表单设计起来很方便,而现实中一个流程中不可能每一步骤的表单都需要很灵活的控制,有的步骤对表单的要求不高,有些步骤则要求较高,那么,我能否在同一流程中根据不同需求混合使用这两种表单呢?针对不同需求设计不同类型的表单呢?
      答案是肯定的,下面我们就以一个简单的例子来演示使用这两种不同的表单完成一个报销的二级审批流程:

      该流程很简单,员工填写报销单,由部门经理一级审批,经理审批通过后,送财务部门进行二级审批。表单只需两个审批表单,在经理审批表单我们将采用上文中的方式,Aspx+ascx来设计审批表单,财务审批我们将采用InfoPath来设计表单界面。

      开始设计之前,我们需要弄清楚一个问题:我的Aspx表单是怎么跟WF关联的呢,而InfoPath表单又是怎么跟WF关联起来的呢?WF是怎么知道我这个流程要调用的是Aspx或InfoPath表单的呢?其实这个问题通过上文的例子就可以得出答案:是ContentType,我们创建任务的用的是CreateTaskWithContentType活动,我们通过该活动的ContentTypeId绑定了其内容类型,也就是我们的Aspx表单页面,这样WF就知道我们的任务是我们自定义的Aspx表单;那么可能有朋友又提出质疑:传统的WF+InfoPath中我没有使用CreateTaskWithContentType活动,流程没有跟InfoPath表单绑定,系统又是怎么知道我要用InfoPath表单的呢?其实在设计前期你已经为WF绑定了InfoPath表单内容类型,查看一下workflow.xml就可以看得出来。

代码

1 <?xml version="1.0" encoding="utf-8" ?>
2 <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
3 <Workflow
4 Name="Janet.AspxWorkflow.Workflow"
5 Description="报销审批流程"
6 Id="02d68356-73a6-4b99-9aba-a09422010fe5"
7 CodeBesideClass="Janet.AspxWorkflow.Workflow.Workflow1"
8 CodeBesideAssembly="Janet.AspxWorkflow.Workflow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0d7c2ff31dd40d01"
9 TaskListContentTypeId="0x01080100C9C9515DE4E24001905074F980F93160"
10 AssociationUrl="_layouts/CstWrkflIP.aspx" >
11 <Categories/>
12 <MetaData>
13 </MetaData>
14 </Workflow>
15 </Elements>

这个WF+Infopath流程时基本的workflow.xml,请注意加蓝色背景的那行,是我们自己手工加上的,系统并不自动添加,正是这个TaskListContentTypeId为WF流程绑定了InfoPath审批的内容类型,也就是指定了你用CreateTask活动创建的任务,该任务默认所使用的内容类型,当然你也可以不在这里指定,直接用CreateTaskWithContentType活动,在ContentTypeId中指定为“0x01080100C9C9515DE4E24001905074F980F93160” 也是可以的。

了解了这些我们可以推测:在同一流程中,为不同的活动指定不同的内容类型,那么是否就可以使用不同类型的审批表单了呢?

下面就开始我们的试验:

一、流程配置

设计一审批流程,一级审批用CreateTaskWithContentType活动,指定内容类型为我们的Aspx页面,二级审批用普通的CreateTask。

 

流程很简单,为了节省图片空间,我把中间折叠了起来。

分别用Ascx和InfoPath来设计我们的审批所用到的两个表单,设计完成后,修改配置文件:

feature.xml

代码

1 <?xml version="1.0" encoding="utf-8" ?>
2 <Feature Id="3da5db31-b080-4568-bca9-9c2c868e3829"
3 Title="Janet.AspxWorkflow.Workflow feature"
4 Description="My SharePoint Workflow Feature"
5 Version="12.0.0.0"
6 Scope="Site"
7 ReceiverAssembly="Microsoft.Office.Workflow.Feature, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
8 ReceiverClass="Microsoft.Office.Workflow.Feature.WorkflowFeatureReceiver"
9 xmlns="http://schemas.microsoft.com/sharepoint/">
10 <ElementManifests>
11 <ElementManifest Location="workflow.xml" />
12 <ElementFile Location="审批表单.xsn"/>
13 </ElementManifests>
14 <Properties>
15 <Property Key="GloballyAvailable" Value="true" />
16 <Property Key="RegisterForms" Value="*.xsn" />
17 </Properties>
18 </Feature>
19

 

workflow.xml

代码

1 <?xml version="1.0" encoding="utf-8" ?>
2 <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
3 <Workflow
4 Name="Janet.AspxWorkflow.Workflow"
5 Description="报销审批流程"
6 Id="02d68356-73a6-4b99-9aba-a09422010fe5"
7 CodeBesideClass="Janet.AspxWorkflow.Workflow.Workflow1"
8 CodeBesideAssembly="Janet.AspxWorkflow.Workflow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0d7c2ff31dd40d01"
9 TaskListContentTypeId="0x01080100C9C9515DE4E24001905074F980F93160"
10 AssociationUrl="_layouts/CstWrkflIP.aspx" >
11 <Categories/>
12 <MetaData>
13 <Task0_FormURN>urn:schemas-microsoft-com:office:infopath:QiXE:-myXSD-2010-05-05T13-38-42</Task0_FormURN>
14 <StatusPageUrl>_layouts/WrkStat.aspx</StatusPageUrl>
15 <ExtendedStatusColumnValues>
16  <StatusColumnValue>经理批准等待财务审批</StatusColumnValue>
17  <StatusColumnValue>经理拒绝</StatusColumnValue>
18  <StatusColumnValue>财务批准流程审批完毕</StatusColumnValue>
19 <StatusColumnValue>财务拒绝</StatusColumnValue>
20 </ExtendedStatusColumnValues>
21 </MetaData>
22 </Workflow>
23 </Elements>
24

请注意加蓝色背景的部分是需要改动的,其他的如<ExtendedStatusColumnValues> 节点则不是必须的,可根据实际情况修改。

 

 二、流程代码编写

 

代码

1 public sealed partial class Workflow1 : SequentialWorkflowActivity
2 {
3 public Workflow1()
4 {
5 InitializeComponent();
6 }
7
8 public Guid workflowId = default(System.Guid);
9 public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();
10 public Guid taskId1 = default(System.Guid);
11 public SPWorkflowTaskProperties taskProperties1 = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();
12 public Guid taskId2 = default(System.Guid);
13 public SPWorkflowTaskProperties taskProperties2 = new Microsoft.SharePoint.Workflow.SPWorkflowTaskProperties();
14 public String completeTask2_TaskOutcome1 = default(System.String);
15 public String completeTask1_TaskOutcome1 = default(System.String);
16 public Int32 setState = default(System.Int32);
17 public string ItemTitle = string.Empty;
18
19 private bool isPmApproved = false; //项目经理审批通过与否
20
21 private void onWorkflowActivated1_Invoked(object sender, ExternalDataEventArgs e)
22 {
23 this.ItemTitle = this.workflowProperties.Item.DisplayName;
24 }
25
26 private void createTaskWithContentType1_MethodInvoking(object sender, EventArgs e)
27 {
28 this.taskId1 = Guid.NewGuid();
29 this.taskProperties1.AssignedTo = "jasper\\moss_test1";
30 this.taskProperties1.ExtendedProperties["step"] = 1; //指定要加载的Aspx表单编号
31 this.taskProperties1.Title = string.Format("请经理审批报销单【{0}】", this.ItemTitle);
32 }
33
34 private void onTaskChanged1_Invoked(object sender, ExternalDataEventArgs e)
35 {
36 this.isPmApproved = bool.Parse(this.taskProperties1.ExtendedProperties["approved"].ToString());
37 string msg = this.isPmApproved ? "经理通过" : "经理拒绝";
38 this.completeTask1_TaskOutcome1 = msg;
39 msg += "" + this.taskProperties1.ExtendedProperties["ApproveMsg"].ToString();
40 this.workflowProperties.Workflow.CreateHistoryEvent(this.isPmApproved ? 2 : 8, 0, this.workflowProperties.OriginatorUser, msg, "", ""); //写入工作流历史记录
41 this.setState = this.isPmApproved ? (int)SPWorkflowStatus.Max : (int)SPWorkflowStatus.Max + 1;
42 }
43
44 //分配财务审批任务
45 private void createTask2_MethodInvoking(object sender, EventArgs e)
46 {
47 this.taskId2 = Guid.NewGuid();
48 this.taskProperties2.AssignedTo = "jasper\\moss_test2";
49 this.taskProperties2.TaskType = 0; //指定InfoPath要加载的表单编号
50 this.taskProperties2.Title = string.Format("请财务部门审批报销单【{0}】", this.ItemTitle);
51 }
52
53 //财务审批
54 private void onTaskChanged2_Invoked(object sender, ExternalDataEventArgs e)
55 {
56 bool approve = bool.Parse(this.taskProperties2.ExtendedProperties["approve"].ToString());
57 string msg = this.isPmApproved ? "财务通过" : "财务拒绝";
58 this.completeTask2_TaskOutcome1 = msg;
59 msg += "" + this.taskProperties2.ExtendedProperties["commons"].ToString();
60 this.workflowProperties.Workflow.CreateHistoryEvent(approve ? 2 : 8, 0, this.workflowProperties.OriginatorUser, msg, "", ""); //写入工作流历史记录
61 this.setState = approve ? (int)SPWorkflowStatus.Max + 2 : (int)SPWorkflowStatus.Max + 3;
62 }
63 }

 可以看出,代码编写与传统的WF+InfoPath开发完全一样,直接指定TaskType=对应InfoPath编号就可以了

 

 三、流程运行测试

 新建一报销申请项目,启动运行,测试流程结果:

 

 新建了一个出差报销的单子

 

 

 点击“报销流程”,启动该流程

 已经为经理分配了审批任务,点击该任务:

 

 看到的是一级审批中的Aspx表单,提交审批

 为财务部门分配了审批,点击链接进行财务审批

 结果在意料之中,正确的加载了InfoPath审批表单,点击“提交”提交审批流程

 

 审批流程执行结束,一切正常,回到我们的报销申请列表

 【总结】

  根据本文提供的方案,习惯了WF+InfoPath开发流程的,可按传统的WF+InfoPath来开发,对于流程中复杂的控制步骤可采用Aspx表单来处理,二者结合起来使用,进而可以根据不同的需求进行不同的设计;而且可以轻松应对现存的用WF+InfoPath已经制作完成的流程的修改或扩充,如替换某一步骤为Aspx表单进行控制,有着重要意义,你只需将该步骤的CreateTask换成CreateTaskWithContentType,指定其ContentTypeId为你的Aspx内容类型就可以顺利实现流程的升级。

  在VS2010中开发Sharepoint2010工作流可直接使用Aspx表单来处理,这对Moss下的流程开发的支持应该是更进一步,,相对Sharepoint2007在工作流这方面改进了不少功能,值得期待。

 

  附件:本文示例源码

 

【Moss开发系列】WF+Aspx进行Moss工作流开发(1)

【Moss开发系列】WF+Aspx进行Moss工作流开发(2)

  

抱歉!评论已关闭.