一步一步学习sharepoint2010 workflow 系列第三部分:自定义SharePoint代码工作流 第8章 自定义Visual Studio工作流(Custom Visual Studio workflows)
■介绍Visual Studio中的工作流程
■创建一个顺序工作流
■创建状态机工作流
■导入SharePoint Designer工作流到Visual Studio
使用Visual Studio去建立你的自定义SharePoint 工作流使你能建立复杂工作流。通过Visual Studio,是无限可能的,你可以从头编写你的工作流,即使你使用的Windows workflow foundation架构。
Visual Studio不是一个新工具。事实上,它首次发布在1997年名字为Visual Studio97,在SharePoint之前存在。这是微软第一次尝试在一个开发环境中包含多种语言(C++、J++、和InterDev)。随着SharePoint2003的到来。Visual Studio2003有了SharePoint的扩展,使能够开发SharePoint的自定义包和部署他们到SharePoint更简单。即使有这样的扩展,你需要大量的知识,这使得他们的价值可以忽略不计.
在2005版本和2008版本没有带来更多的扩展和更高的功能对于SharePoint而言。直到2010版本的Visual Studio使SharePoint开发人员终于感觉是一流公民。在该版本中,SharePoint开发者获取了F5的经验。他们点击F5,所有他们自定义的都会自定打包饼部署到SharePoint。鉴于SharePoint开发者在之前的2003和2007版本的学习曲线很陡峭,Visual Studio2010肯定会让所有的开发者松一口气。
在工作流开发中,有些包和部署利于应用。当你创建一个新的SharePoint工作流项目,所有必要功能和包文件将被创建。点击F5,你的工作流被发送到SharePoint 并准备测试.
因为Visual Studio2010那么容易,你不用担心无论你想去建立一个顺序或者状态机工作流。如果你还记得第一章,顺序工作流总是往一个方向流动。状态机工作流会有不同的状态直到工作流逻辑告诉他们结束。无论你选择哪条路,你会使用相同技术拖放活动到设计界面,以及相同的调试和版本技术.
如果你觉得顺序工作流工作比较舒适,你可以从Visual Studio2010的新功能中受益--这个能力是导入一个SharePoint Designer工作流。 这个有用的原因很多,下面有个例子。假设你有一个存在的SharePoint Designer工作流,一年以后,你的业务需求变得更加复杂。这种复杂的增加,有必要使用Visual studio工作流。这个时候你不需要从头开始,只要到如你现有的工作流进行增加和修改。
8.1 Visual Studio 工作流介绍 (Introducing Visual Studio workflows )
一个Visual Studio SharePoint工作流由三个基本项组成:模板,部署构建和类型。模板通常叫做设计界面,区域可以拖放工作流活动和流的结构,通过工作流导航。活动是可重用的代码块。通过可视化可以知道工作流是做什么的,从界面上提高了可读性,并简化维护。
部署构件是一个令人兴奋的功能在Visual Studio中。Visual Studio工作流是部署SharePoint的功能和解决方案包。 一个解决方案包封装和部署工作流到SharePoint。当激活,功能将启用。在SharePoint2007,工作流部署是同样的方式。 你需要去创建这些构件从头开始或者依靠不支持的第三方工具。而在Visual Studio2010中,这些构件是自动创建的,只需要知道一点点内部运作。
一个工作流始终是一种类型。它是顺序或者状态机。要改变工作流类型,你必须重新创建它。
8.1.1 工作在工作流模板( Working with the workflow’s template )
当你首次创建你的Visual Studio项目使用工作流模板之一,一个自动生成的工作流标题是Workflow1将在这个项目中。当你双击该文件,工作流模板将加载(图8.1),显示工作流设计界面。有了这个模板,你可以开始拖放活动和工作流结构。
图8.1
在模板左边的是工具栏(图8.2),其中包含所有的开箱即用的活动,你可以多放到模板上。一般情况下,根据经验放置所有的代码到活动上, 然后使用模板确定位置。例如,你可以右击活动并选择生成处理程序。这将创建模板的代码隐藏方法,在那里你可以添加代码。如果此代码需要在其他工作流中重复使用,最好封装成一个复合活动。一个符合活动是一个自定义活动可以调用其他活动。然后,地带模板中添加的代码,你可以拖放你的复合活动到模板上。第11章将详细讲解。
图8.2
开始建立自定义活动之前,注意这里有很多开箱即用活动可以使用。他们很强大,需要很少的配置。表8.1和8.2列出前十基本活动和他们的用途
表8.1
表8.2
8.1.2 工作流部署构件(Workflow deployment artifacts )
如前所述,一个SharePoint工作流是封装在解决方案包中部署到SharePoint上的。此后,它依赖SharePoint站点的激活功能加入到站点的工作流, 库,等等。当你创建一个新的SharePoint工作流项目在Visual Studio中,包和feature是自动创建和配置的(图8.3)。
图8.3
图8.4
重要的是记住向导是假设本地安装了SharePoint,它不支持远程部署。你应该在本地安装SharePoint2010(例如,在你的个人电脑)可以做你的开发和单元测试。
在完成测试你的工作流之后,你可以手工安装和部署解决方案包到另外的环境。 即使解决方案包和feature自动创建了,重要的是要知道一点手工工作。一些高级技术要求更多的知识,所以让我们简单的看看这些文件是怎么制作的,并且如何工作的。
你开始挖掘解决方案包。从技术上讲,你不必使用包。包是部署的工具,它允许你保证跨越服务器的一致性,因为它替代手工拷贝和部署文件, 这些由包来工作。所有的工作流需要一个动态链接库(DLL)并且激活feature。但是比手工拷贝文件,还是让包帮我们去创建。当你双击Package.package,你看到图形用户界面像图8.5.注意有两个主要的区域在图8.5-左边区域显示解决方案里有什么和右边区域显示包里有什么。 左边面板显示在解决方案中的可用于添加到包的SharePoint项但是尚未添加。如果你点击向左或向右的箭头,你可以移动对象进出包。注意这里有两个feature;一个是在包中,另一个是没有的。
图8.5
你还可以使用package Exporer(图8.6)去深入包的内容。图8.6显示包里有一个feature。里面的那个是一个工作流。当包部署,并且feature被激活,工作流将准备被使用。
图8.6
在package的底部,你可以看到三个选项卡(图8.7)。这个设计选项卡是当你双击在解决方案资源管理器中的package看到的GUI。package是一个cab的XML清单文件。这个GUI是生成你的XML清单。如果你一直想去手动操作XML,切换到清单选项卡,你可以开始直接编辑XML文件。高级选项卡允许你去从包中添加和移除程序集。也许你有第三方程序集你也可以部署到包中。
图8.7
双击在解决方案资源管理器中的Feature1.feature。你将看到一个不同的GUI(图8.8)看起来像包的GUI。在左边,你将看到SharePoint自定义的那些可用来添加到feature但是没有添加进来的。在右边的选项是已经添加的项目。图8.8显示的那个feature包含一个工作流名字叫Workflow1.这里是第二个工作流和一个WebPart没有被添加。当这个feature被激活仅仅Workflow1将被启用。
图8.8
8.1.3 (顺序 VS 状态机 工作流)Sequential vs state machine workflows
工作流执行在处理中从一个步骤到另外一个有两条路。工作流可能是:
■ 顺序,在这个范围内的工作流按步骤顺序执行,一个步骤在另外一个步骤之后。
■ 状态机 ,它没有执行的顺序
顺序工作流总是向前进行的,永远不会回到上一步。图8.9显示一个顺序工作流看起来像在Visual Studio工作流设计器界面上的。
图8.9
图8.10
当你创建一个新的Visual Studio项目,你将需要去决定哪种类型的工作流。建立新项目向导(图8.11)将显示两个工作流项目类型。项目模板选择不是至关重要的,因为工作流是在项目中的一项,不是项目本身。如果你选择顺序项目模板,你可以随时删除自动生成的顺序工作流并替换成状态机工作流。记住这不是升级,所以重要的是你的需求。
图8.11
显然,一些业务流程将需要状态机工作流。重要的是思考你的业务流程需求在你开始建立一个自定义工作流之前,因为它是难以改变的过程在你开始之后。如果你开始建立一个顺序工作流但是之后又决定它应该是状态机工作流,你开始建立的都不能用了。底线是思考你的业务需求后开始。
8.2 (建立一个顺序工作流)Building a sequential workflow
现在到了在Visual Stuio中建立你的第一个SharePoint工作流。顺序工作流是没有状态机复杂。要添加一些真实世界中的例子,你将建立一个工作流跟踪维护工作订单的处理。该场景设计一个大学需要一个系统为学生去提交维修请求为他们的宿舍。当学生提交一个工作订单,该订单时分配给维护人员,当维护人员完成工作,关闭订单并完成工作流。图8.12显示该工作流将采取的快乐的路径。
图8.12
我使用“快乐的路径”因为我们都知道业务流程是没有那么简单的。通常情况下,这个过程已经替代了路径工作流需要依靠环境而定。此外,当你在技术方面的因素,所以工作流简化了。
考虑你如何在SharePoint中完成这个例子。你将需要一个列表标题叫Work Orders ,学生能添加项目。之后一个项目被添加,工作流需要等待工作订单的状态变化。你将有四种可能:
■ Pending Assignment
■ Pending Completion
■ On Hold
■ Completed
当经理分配项目给维修人员,他们将改变状态直到pending状态在某一时间完成。你的工作流然后需要去唤醒和发email给维修人员通知他们有新的订单。要做到这点,你需要利用OnWorkflowItemChanged活动。这个活动坐等该项在工作流运行时的改变。在这里,当一个改变发生,你想去看状态列的状态改变。如果状态有改变,你将采取动作。如果状态没有改变,你继续等待。图8.13显示工作流的表现。
图8.13
你可能想到这一点如果你还在建立顺序工作流。单按是肯定的。你可以使用一个While循环去保持循直到状态设置为OnHold或者Completed。 如果这个状态不是设置成其中一个,工作流将循环并使用OnWorkflowItemChanged活动继续等待。注意循环是重要的因为你不能在SharePoint Desginer工作流中循环。另一方面的原因是你可能要考虑到Visual Studio工作流好于SharePoint Designer。
图8.14显示新的工作订单表单看起来像为提交订单的学生提供的。另外,维修人员可能使用相同表单当他们改变订单状态到Completed。注意状态列和分配列。通常情况下,你不会希望学生看见这些字段。你可能使用一个自定义InfoPath表单去隐藏这些字段如果是学生,但是经理和维修人员需要显示他们。参与第7章,“Custom form fundamentals”,提供更多的详细信息。
图8.14
随着布景设置,让我们开始建立工作流。打开Visual Studio2010,并创建一个新的项目通过点击文件->新项目。当项目模板填出,选择顺序工作流模板。项目标题为WorkOrderprocessing。当你创建了项目,输入你的SharePoint站点的URL,并绑定工作流到你的Work Orders Custom列表,这个列表有一些列类似图8.14.(图8.15显示向导界面当你绑定你的工作流到列表)
图8.15
重要的调试,错误处理,和工作流版本-调试,错误处理和Visual Stuido工作流版本是重要的技术,一个工作流开发人员应该知道。第12章有关于这些主题的扩展讨论。
双击Workflow1并配置高级的活动如while loop,OnWorkflowItemChanged和If-Else分支(表8.3)
表8.3
图8.16
现在已经拖放好While循环和If-else分支,下一步去添加活动到每个If-else分支去处理你的业务需求。你希望发生的事情如下:
随着分支的正确配置,添加活动到分支去发送邮件和执行一些日志。按照表8.4的步骤去配置分支。
表8.4
清单8.1
首先,清单8.1上的代码获取assignedTo列,并强转它到一个SPFieldUser对象(第一点)。然后,这个值所在的字段强转成一个SPFieldUserVlaue对象(第二点)。从这个对象,你能获取SpUser对象是存储在AssignedTo列的信息。你需要这个对象去获得用户email地址和分配发送邮件(第三点)。
续表8.4
所有的活动放置完毕,你几乎可以建立和测试工作流。你准备开始之前,你需要解决每个if分支的红色惊叹号。惊叹号告诉你该分支没有方法 告诉分支如果条件满足或者不满足。按照下面表8.5步骤去添加逻辑到分支使他们能确定如果条件是满足的。
表8.5
清单8.2
此代码首先找到AfterProperties属性的Status(第1段代码)。这将包含status列更新后提交到数据库的值。 (第2段代码)检查BeforeProperties是否为null是必须的因为如果工作项是新的,它不会有之前的值。最后, 如果之前和之后的Status是相等的,返回true,因为Status列没有被更新(第3段代码)。
续表8.5
随着最后步骤的设置,你现在准备部署和测试工作流,右击解决方案,选择部署解决方案,进行部署。这将建立项目并生成解决方案包。它将添加和部署包到SharePoint。
导航到你的work orders 列表,创建一个新项,并分配给一个用户。该动作揭开工作流的序幕,工作流应该找到自身在进程中的状态。这时,工作流是位于OnWorkflowItemChanged活动的,并等待有人来编辑workOrder。编辑work Order通过改变Status到Pending Completion。
工作流仍然在进程中,并再次等待项目的更改。再次编辑work order;这时设置Status到Completed。这个动作将发送 email给发起者,并且工作流将终止。如果你点击在工作流上的Status显示Completed,你将被带到工作流历史列表类似图8.17 。
图8.17
8.3 (建立状态机工作流)Building a state machine workflow
上一节你建立顺序工作流是有用的。它帮你管理大学校园学生维修请求流程。如果业务需求更加复杂,工作流能迅速分解。例如注意图8.18额外的步骤工作订单完成和工作流终止。如果业务规则要求学生确认工作完成的满意度。如果满足,工作流将终止,如果不满足,工作流需要回去到Pending Assignment状态,经理可以派另外的维修人员完成这个工作。
图8.18
这个需求顺序工作流将难以满足;状态机工作流比较合适。你可能使用顺序工作流通过更多While活动或者添加复杂的逻辑跟踪, 但是走上这条路将创建维护恶梦。
图8.19显示如果你去重写顺序工作流改成状态机工作流的样子。如果你还记得,顺序工作流只有两个状态,In Progress和Completed, 许多逻辑填在In Progress状态。图8.19显示6个状态,而不是两个。注意如何使工作流能简单的回到前一个状态。它不是顺序的。另外, 如果你记得前面的例子,当工作订单状态放在On Hold,工作流终止。状态机工作流是允许无限期定位在该状态或直到经理决定工作订单返回。
图8.19
首先,创建一个新项目使用状态机项目模板。当你的工作流载入,你将看到模板不同于之前的顺序工作流模板。你将获得一个状态有一个 StateInitialization活动在里面。重命名默认状态为New。当你做这件事,你将注意一个红色惊叹号文本在状态机工作流附近。右击这个这个文本 并选择属性。更改InitialStateName属性为New。这是告诉状态机当它首次启动时应该是哪个状态。
你配置好New状态之后,添加5个状态到模板上通过拖放state活动从工具箱上。使用一下State名称:
■ New
■ PendingAssignment
■ InProgress
■ PendingValidation
■ Completed
■ OnHold
对于Complete状态,拖放StateInitalization活动。在所有其他的State,拖放EventDriven活动。为了可以工作,每个State需要一个EventDriven活动或者一个StateInitialization活动。所有的States除了Completed 状态需要去等待他们执行之前的动作出现。该动作是修改工作流项目并处理EventDriven活动。Completed状态并不需要事件出现,因为它将终止工作流。
你拖放好所有的EventDriven(和StateInitialzation)活动到State之后,重命名他们为有意义的描述:
■ WaitForAssignment (PendingAssignment state)
■ WaitForCompletion (InProgress state)
■ WaitForValidation (PendingValidation state)
■ WaitForResume (OnHold state)
■ CompleteWorkflow (Completed state)
随着你的State和EventDriven活动进入位置,现在告诉工作流不同State之间的关系。从本质上讲,做出来的状态机工作流看起来像图8.19. 状态机模板有个有用的功能使允许你去连接不同State通过箭头。这是类似Visio图表。像图8.19,你在模板的状态之间画出箭头。工作流知道 哪个State来自哪里通过箭头方向。
开始连接你的State,悬停鼠标在New状态,并寻找四个蓝色的圆点在State的边框上。点击并按住这个圆点并拖动你的光标悬停在PendingAssignment 状态。悬停在PendingAssignment状态的蓝点并释放鼠标。这将绘制箭头在New状态和PendingAssignment状态。请确定箭头是朝正确的方向。
重复此步骤直到所有State都连接完成。你的模板看起来类似图8.19,更具体地说,像图8.20你就完成了。
图8.20
图8.21
要建立出工作订单的示例,你只需要去添加你的活动到各个状态中。例如PendingAssignment状态(图8.22)。因为根活动是EventDriven活动,第一个活动必须等待事件的触发。在这里,你需要再次使用OnWOrkflowItemChanged活动。当工作流是在这个状态,它将等待工作订单被更新。当它更新后,三个连续的If块决定准备做什么。第一个检查如果AssignedTo列是空值。如果它是,它重复PendingAssignment状态。否则,它将去看状态列。第二个分支检查如果状态设置为InProgress,如果它是,工作流移动到InPrgoress状态并发送邮件给分配人。最后,如果状态是设置为OnHold,工作流移动到OnHold状态。
图8.22
InProgress 状态(图8.23)的行为类似PendingAssignment状态。最大的区别是,针对不同分支逻辑检查。在InProgress状态的工作流等待维修人员去完成工作订单,当他们完成工作订单,将更新Status列为Completed.这导致OnWorkflowItemChanged事件再次触发,它是由第二个分支处理的,然后前往PendingValidation状态。其他状态重复到InProgress或者到Hold状态。
图8.23
当工作订单完成后,状态进入PendingValidated,通过发送邮件去验证完成的工作的满意度。有几种方法可以完成此事。一个选择是在邮件中嵌入链接。当用户点击链接,去向一个网页,读出唯一的ID,通过编程更新。你可以使用“YES"或"NO"列在工作订单上去跟踪如果学生验证了工作。
图8.24
最后是Completed状态(图8.25)。工作流终止是Completed状态。你可以放置Terminate活动到第二个分支在PendingValidation状态上;但是 你的工作流将终止但仍显示PendingValidation在工作流状态列上。
图8.25
8.4 导入一个SPD工作流到Visual Studio中(Importing an SPD Workflow into Visual Studio)
一个令人兴奋的新功能是Sharepoint2010和Visual Studio2010是能够从Sharepoint Designer(SPD)导入工作流到Visual Studio中的。这带来了很高的商业价值以为内在SPD创建的工作流可以很容易的导入和导出。另外非技术资源能在SPD上建立工作流原型,可以做更多的技术工作.
它很容易做到这一点。高级的步骤包括导出工作流模板从SPD中。当你导出工作流,它保存在网站集的根站点的网站资产库。文件为.WSP的扩展名文件。你可以下载该文件到你的计算机,并创建一个新的Visual Studio项目。当你选择项目类型,选择导入重用工作流,并浏览你下载的.WSP文件。 就这么简单!表8.6显示更细的步骤。
表8.6
图8.26
下一章
一步一步学习sharepoint2010 workflow 系列第三部分:自定义SharePoint代码工作流 第9章 Visual Studio工作流表单(Forms in Visual Studio workflows)
目录
一步一步学习sharepoint2010 系列篇开更了有感,希望大家多多捧场啊,倾情奉献
本人声明
本博客内的文字和图片除标明出处和转贴的外,均系本人原创作品,如转载或使用,不是用于盈利目的,尽请使用,但请注明引自这里和作者的名字;有商业用途的,请与本人联系,协商后再作使用,否则我将采取法律手段维护自己的利益。谢谢合作。meiweijun@163.com