Chinaunix首页 | 论坛 | 博客
  • 博客访问: 8350965
  • 博文数量: 444
  • 博客积分: 10593
  • 博客等级: 上将
  • 技术积分: 3852
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-09 15:26
文章分类

全部博文(444)

文章存档

2014年(1)

2013年(10)

2012年(18)

2011年(35)

2010年(125)

2009年(108)

2008年(52)

2007年(72)

2006年(23)

分类: 系统运维

2007-12-12 19:43:16

 
7.测试工作流

现在来测试一下刚才设计的工作流.

打开SharePoint文档中心 > 文档,上传一个文档,为其启动WhileInDesigner工作流.

打开任务,编辑WhileInDesigner工作流创建的Task In While?任务,点击完成任务,这时Task In While?任务和WhileInDesigner工作流的状态都是已完成.

修改XOML实现循环

1.SharePoint Designer生成的文件

回到SharePoint Designer,我们发现SharePoint Designer自动生成了以下文件:

l  Task In While_003f_.aspx : Task In While?任务的寄主页

l  WhileInDesigner.aspx : 工作流初始化页

l  WhileInDesigner.xoml : 工作流定义文件

l  WhileInDesigner.xoml.rules : 工作流规则文件

l  WhileInDesigner.xoml.wfconfig.xml : 工作流配置文件

右键单击WhileInDesigner.xoml,选择XML方式打开.


可以看到如下
XOML文件:

 

2.根元素:RootWorkflowActivityWithData元素

从根元素RootWorkflowActivityWithData的三个名称空间可以看出,SharePoint Designer设计的工作流需要Windows Workflow FoundationWindows SharePoint Services 3.0共同支持.

3.替换IfElseActivity

继续往下看,IfElseActivity元素表示我们添加的条件,它对应于WinWF中的IfElseActivity活动.XOML,WinWF元素和活动的名称是相同的.

SharePoint Designer设计的工作流中,步骤总是SequenceActivity元素或者IfElseActivity元素.

所以这里我们将IfElseActivity元素替换为SequenceActivity元素.

IfElseActivity活动的每一条分支都是一个IfElseBranchActivity活动,我们不再需要它,把它修改为WhileActivity.

IfElseBranchActivity.Codition改为WhileActivity.Codition.

这就是我们之前设计工作流时添加条件的目的,利用条件来生成我们需要的规则文件,因为在本文中,WhileActivity循环的条件也是finish=false.

现在原来的IfElseActivity已经被修改为SequenceActivity和及其子元素WhileActivity.

4.WhileActivity的子活动

WinWF, WhileActivity有且只能有一个子活动,然而我们现在的WhileActivity中却包含了多个子活动(基本上一个元素就是一个子活动),所以我们还需要添加一个SequenceActivity将其余的子活动包含在内.

然后我们来看看这些SequenceActivity的子活动们.

5.LookUpActivitySharePoint Designer自动生成的变量

LookUpActivity的名称空间前缀是ns0,表示它是一个SharePoint Workflow Action.

有过Visual Studio工作流开发经验的朋友一定会想起CreateTask等活动,不错,LookUpActivityCreateTask活动同属于SharePoint Workflow Actions,但却有所不同, CreateTask等活动被Visual Studio 2005 Designer for Windows Workflow Foundation支持,支持编码开发;LookUpActivity等活动基于定义和规则,且不被Visual Studio 2005 Designer for Windows Workflow Foundation支持.

LookUpActivity的作用是从指定的列表项中获取某一域的值,这里,它从我们上传的文档中获取上传者的名称,并将其存储在变量_x005f_String0.

_x005f_String0SharePoint Designer自动生成的变量.其前缀_x005f_表示它是由SharePoint自动生成的,如果没有此前缀,那么我们可以在SharePoint Designer工作流设计器中看到此变量,中间的String表示其类型,末位0表示序号(这也是SharePoint Designer自动生成的中间变量的命名规则).

6.CollectDataTask

CollectDataTask用来收集用户数据(创建任务),它的属性描述了该任务的内容类型,分配对象,标题,甚至GUID(CollectDataTask将任务的TaskID绑定到了变量taskID).

7.FindValueActivity

FindValueActivity的作用大概和LookUpActivity差不多,但是FindValueActivity会提供一个默认值,本文的实验中它的存在与否似乎无关紧要,于是删之.

8.又一个LookUpActivity

接着又是一个LookUpActivity,将其ListItem属性值中的_x005f_Int320修改为taskID,这样LookUpActivity就会从Task In While?任务中获取canFinish域的值并将其存储在变量_x005f_Boolean0

9.SetVariableActivity

SetVariableActivity是一个给变量赋值的活动,这里它将_x005f_Boolean0的值赋给变量finish.

10.最终的XOML文件及其逻辑

OK,所有活动已经介绍并且修改完毕,最终的XOML文件内容如下:

<ns0:RootWorkflowActivityWithData x:Class="Microsoft.SharePoint.Workflow.ROOT" x:Name="ROOT" xmlns="" xmlns:x="" xmlns:ns0="clr-namespace:Microsoft.SharePoint.WorkflowActions;Assembly=Microsoft.SharePoint.WorkflowActions, Version=12.0.0.0, Culture=neutral, PublicKeyToken=null">

     <ns0:RootWorkflowActivityWithData.WorkflowFields>

         <ns0:WorkflowDataField Name="__list" Type="System.String" />

         <ns0:WorkflowDataField Name="__item" Type="System.Int32" />

         <ns0:WorkflowDataField Name="__context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext" />

         <ns0:WorkflowDataField Name="__initParams" Type="Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties" />

         <ns0:WorkflowDataField Name="__workflowId" Type="System.Guid" />

         <ns0:WorkflowDataField Name="finish" Type="System.Boolean" />

         <ns0:WorkflowDataField Name="taskId" Type="System.Int32" />

         <ns0:WorkflowDataField Name="_x005f_String0" Type="System.String" />

         <ns0:WorkflowDataField Name="_x005f_Boolean0" Type="System.Boolean" />

         <ns0:WorkflowDataField Name="_x005f_Int320" Type="System.Int32" />

     ns0:RootWorkflowActivityWithData.WorkflowFields>

     <ns0:OnWorkflowActivated WorkflowProperties="{ActivityBind ROOT,Path=__initParams}" x:Name="ID1">

         <ns0:OnWorkflowActivated.CorrelationToken>

              <wf0:CorrelationToken Name="refObject" OwnerActivityName="ROOT" xmlns:wf0="" />

         ns0:OnWorkflowActivated.CorrelationToken>

     ns0:OnWorkflowActivated>

     <ns0:ApplyActivation __Context="{ActivityBind ROOT,Path=__context}" x:Name="ID2" __WorkflowProperties="{ActivityBind ROOT,Path=__initParams}" />

     <SequenceActivity x:Name="ID6" Description="步骤?1">

         <WhileActivity x:Name="ID3">

              <WhileActivity.Condition>

                   <RuleConditionReference ConditionName="__Rule_ID3_1" />

              WhileActivity.Condition>

              <SequenceActivity x:Name="subSequence">

                   <ns0:LookupActivity ListId="{}{A4716DC6-6214-4B4E-A400-BBEEEFBA74CD}" x:Name="ID9" FieldName="Author" LookupFunction="LookupUser" __Context="{ActivityBind ROOT,Path=__context}" ListItem="{ActivityBind ROOT,Path=__item}">

                       <ns0:LookupActivity.ReturnValue>

                            <ActivityBind Name="ROOT" Path="_x005f_String0" />

                       ns0:LookupActivity.ReturnValue>

                   ns0:LookupActivity>

                   <ns0:CollectDataTask x:Name="ID8" ContentTypeId="0x01080100D337657FD8FFC44B8D75294F67F6900E00E892A7A4399FB5499230A2887D54EDD4" TaskId="{ActivityBind ROOT,Path=taskId}" Title="Task In While?" InProperties="{x:Null}" __Context="{ActivityBind ROOT,Path=__context}" OutProperties="{x:Null}" AssignedTo="{ActivityBind ROOT,Path=_x005f_String0}" />

                   <ns0:LookupActivity ListId="{}{B0880D9F-DD1C-47AA-9369-FB1081BF054C}" x:Name="ID11" FieldName="canFinish" LookupFunction="LookupBool" __Context="{ActivityBind ROOT,Path=__context}" ListItem="{ActivityBind ROOT,Path=taskId}">

                       <ns0:LookupActivity.ReturnValue>

                            <ActivityBind Name="ROOT" Path="_x005f_Boolean0" />

                       ns0:LookupActivity.ReturnValue>

                   ns0:LookupActivity>

                   <ns0:SetVariableActivity x:Name="ID10" ValueType="System.Boolean">

                       <ns0:SetVariableActivity.Variable>

                            <ActivityBind Name="ROOT" Path="finish" />

                       ns0:SetVariableActivity.Variable>

                       <ns0:SetVariableActivity.Value>

                            <ActivityBind Name="ROOT" Path="_x005f_Boolean0" />

                       ns0:SetVariableActivity.Value>

                   ns0:SetVariableActivity>

              SequenceActivity>

         WhileActivity>

     SequenceActivity>

ns0:RootWorkflowActivityWithData>

如我们之前的描述,工作流启动之后,WhileActivity将检查变量finish的值,如果为false(默认就是false),则执行WhileActivity的子活动.

WhileActivity的子活动的执行过程是:LookUpActivity获取文档的创建者, CollectDataTask为文档创建者分配任务,待任务完成后, LookUpActivity获取任务中canFinish域的值, SetVariableActivity将其值赋给变量finish.

子活动执行完毕,WhileActivity再次检查finish的值,而此时finish的值可能被SetVariableActivity改变,从而根据此值来继续或停止循环.

11.工作流的关联与测试

现在保存XOML文件并关闭,然后双击以工作流方式打开,因为我们修改了XOML文件,所以相比之前的图片有所区别.


步骤
1中只包含一个操作:子步骤(ID:ID3).在该工作流的XOML文件中可以看到,ID3正是WhileActivityID,说明SharePoint Designer可以识别WhileActivity,但无法正确的将其表示出来.

点击完成来完成工作流与文档的关联,如果忽略了这一步,SharePoint中的工作流将不发生任何变化.

最后来测试一下,编辑任务时,不要勾选canFinish,则工作流会自动再分配一项任务,直到你勾选了canFinish.


总结

通过修改SharePoint Designer生成的XOML文件,使SharePoint Designer设计的工作流能够支持WhileActivity,那我们也有理由相信它可以支持更多的WinWF活动.

而且,SharePoint Workflow Actions中的两类活动虽然使用方法不尽相同,但是实现的功能却是一样的(CreateTaskCollectDataTask),这是不是意味着使用Visual Studio开发的工作流也可以使用SharePoint Designer间接的设计出来?

虽然经过修改的工作流已经无法在SharePoint Designer中再设计,那么我们可不可以扩展SharePoint Designer的工作流设计器使其支持更加复杂的工作流?或者干脆开发第三方工作流设计工具?

留待慢慢研究

阅读(2285) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~