开发自定义的SharePoint 顺序工作流
2011-09-07 22:18
183 查看
假设有这样一个需求:
客户需要用Moss2010有个一个请假单(绑定有工作流),有这样几个用户(角色):1.Moss (员工)、2.Leader(组长)、3.Manager(经理)、4.Boss(老板)
当员工创建请假单时,启动工作流。工作流具体需求为,当员工新建了一张新的请假单时,发送邮件给Leader,请他审批,如果Leader在两天内审批(同意或拒绝)工作流结束,但如果Leader在两天内没有审批,则发送邮件给Manager请求Manager审批,如果Manager再两天内审批(同意或拒绝)工作流结束,如果Manager在两天内没有审批,则发送邮件给Boss,请求他审批该请假单,如果Boss在一天内审批(同意或拒绝)工作流结束,如果Boss在一天内审批没有审批则该单据自动生效(自动审批通过),工作流结束。
分析:考虑以上需求用MossoutOfBox 工作流和SharePointdesigner 设计的工作流都不太好实现,因此采用开发自定义的SharePoint顺序工作流。
步骤如下:
1. 启动VS2010 ->New ->Project->VisualC#->SharePoint->2010 (先择Sequential Workflow,点击OK)
选择AskForLeaving这个列表作为该工作流的绑定对象
2. VS2010 默认情况下会自动添加一个onWorkflowActivated1,在onWorkflowActivated1下面添加一个WhileActivity, 在 While Activity中添加一个delayActivity, 在WhileActivity下面添加一个 codeActivity:
3. 转到代码视图,添加如下代码 (在类中加入如下成员)
4. 配置 onWorkflowActivated1
a. 转到工作流审计界面
b. 选中onWorkflowActivated1,在Invoke(Handlers) 中输入OnActived 并按回车,VS会自动创建一个OnActived方法,在其中加入下列代码
5. 配置delayActivity1,将其TimeoutDuration设置为00:05:00,表示该活动将会将工作流延迟5分钟再向下执行(注因为SharePoint的Timer是每五分钟处理一次工作流事件,所以延迟5分钟最长可能让InitializeTimeoutDuration中的代码10才执行一次),在delayActivity1_InitializeTimeoutDuration 中添加如下代码:
6. 配置codeActivity1,在codeActivity1_ExecuteCode 中发送邮件通知用户审批结果
发送邮件的代码请参考http://blog.csdn.net/farawayplace613/article/details/6759538
以下是完整代码Workflow1.cs:
Workflow1.designer.csWorkflow1.designer.cs:
客户需要用Moss2010有个一个请假单(绑定有工作流),有这样几个用户(角色):1.Moss (员工)、2.Leader(组长)、3.Manager(经理)、4.Boss(老板)
当员工创建请假单时,启动工作流。工作流具体需求为,当员工新建了一张新的请假单时,发送邮件给Leader,请他审批,如果Leader在两天内审批(同意或拒绝)工作流结束,但如果Leader在两天内没有审批,则发送邮件给Manager请求Manager审批,如果Manager再两天内审批(同意或拒绝)工作流结束,如果Manager在两天内没有审批,则发送邮件给Boss,请求他审批该请假单,如果Boss在一天内审批(同意或拒绝)工作流结束,如果Boss在一天内审批没有审批则该单据自动生效(自动审批通过),工作流结束。
分析:考虑以上需求用MossoutOfBox 工作流和SharePointdesigner 设计的工作流都不太好实现,因此采用开发自定义的SharePoint顺序工作流。
步骤如下:
1. 启动VS2010 ->New ->Project->VisualC#->SharePoint->2010 (先择Sequential Workflow,点击OK)
选择AskForLeaving这个列表作为该工作流的绑定对象
2. VS2010 默认情况下会自动添加一个onWorkflowActivated1,在onWorkflowActivated1下面添加一个WhileActivity, 在 While Activity中添加一个delayActivity, 在WhileActivity下面添加一个 codeActivity:
3. 转到代码视图,添加如下代码 (在类中加入如下成员)
bool isWorkFlowPending = true; // 用于标记工作流对应的单据是否在等待审批 DateTime startTime = DateTime.Now; // 用于记录工作流启动的时间
4. 配置 onWorkflowActivated1
a. 转到工作流审计界面
b. 选中onWorkflowActivated1,在Invoke(Handlers) 中输入OnActived 并按回车,VS会自动创建一个OnActived方法,在其中加入下列代码
this.startTime = DateTime.Now; // Send mail to Leader for request approval
5. 配置delayActivity1,将其TimeoutDuration设置为00:05:00,表示该活动将会将工作流延迟5分钟再向下执行(注因为SharePoint的Timer是每五分钟处理一次工作流事件,所以延迟5分钟最长可能让InitializeTimeoutDuration中的代码10才执行一次),在delayActivity1_InitializeTimeoutDuration 中添加如下代码:
if (workflowProperties.Item["Status"].ToString().Equals("Approved") || workflowProperties.Item["Status"].ToString().Equals("Rejected")) { this.isWorkFlowPending = false; } else { DateTime now = DateTime.Now; int days = (now - this.startTime).Days; if (days == 2) { // Send mail to Manager for request approval } else if(days == 4) { // Send mail to Boss for request approval } else if (days == 6) { workflowProperties.Item["Status"] = "Approved"; workflowProperties.Item.Update(); } }
6. 配置codeActivity1,在codeActivity1_ExecuteCode 中发送邮件通知用户审批结果
// Send mail to theuser notify that record has been approved or rejected
发送邮件的代码请参考http://blog.csdn.net/farawayplace613/article/details/6759538
以下是完整代码Workflow1.cs:
using System; using System.ComponentModel; using System.ComponentModel.Design; using System.Collections; using System.Drawing; using System.Linq; using System.Workflow.ComponentModel.Compiler; using System.Workflow.ComponentModel.Serialization; using System.Workflow.ComponentModel; using System.Workflow.ComponentModel.Design; using System.Workflow.Runtime; using System.Workflow.Activities; using System.Workflow.Activities.Rules; using Microsoft.SharePoint; using Microsoft.SharePoint.Workflow; using Microsoft.SharePoint.WorkflowActions; namespace SequentailWFDemo.Workflow1 { public sealed partial class Workflow1 : SequentialWorkflowActivity { public Workflow1() { InitializeComponent(); } public Guid workflowId = default(System.Guid); public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties(); bool isWorkFlowPending = true; DateTime startTime = DateTime.Now; private void OnActived(object sender, ExternalDataEventArgs e) { this.startTime = DateTime.Now; // Send mail to Leader for request approval } private void IsWorkFlowPending(object sender, ConditionalEventArgs e) { e.Result = this.isWorkFlowPending; } private void codeActivity1_ExecuteCode(object sender, EventArgs e) { // Send mail to the user notify that record has been approved or rejected } private void delayActivity1_InitializeTimeoutDuration(object sender, EventArgs e) { if (workflowProperties.Item["Status"].ToString().Equals("Approved") || workflowProperties.Item["Status"].ToString().Equals("Rejected")) { this.isWorkFlowPending = false; } else { DateTime now = DateTime.Now; int days = (now - this.startTime).Days; if (days == 2) { // Send mail to Manager for request approval } else if(days == 4) { // Send mail to Boss for request approval } else if (days == 6) { workflowProperties.Item["Status"] = "Approved"; workflowProperties.Item.Update(); } } } } }
Workflow1.designer.csWorkflow1.designer.cs:
using System; using System.ComponentModel; using System.ComponentModel.Design; using System.Collections; using System.Drawing; using System.Reflection; using System.Workflow.ComponentModel.Compiler; using System.Workflow.ComponentModel.Serialization; using System.Workflow.ComponentModel; using System.Workflow.ComponentModel.Design; using System.Workflow.Runtime; using System.Workflow.Activities; using System.Workflow.Activities.Rules; namespace SequentailWFDemo.Workflow1 { public sealed partial class Workflow1 { #region Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> [System.Diagnostics.DebuggerNonUserCode] private void InitializeComponent() { this.CanModifyActivities = true; System.Workflow.Activities.CodeCondition codecondition1 = new System.Workflow.Activities.CodeCondition(); System.Workflow.ComponentModel.ActivityBind activitybind2 = new System.Workflow.ComponentModel.ActivityBind(); System.Workflow.Runtime.CorrelationToken correlationtoken1 = new System.Workflow.Runtime.CorrelationToken(); System.Workflow.ComponentModel.ActivityBind activitybind1 = new System.Workflow.ComponentModel.ActivityBind(); this.delayActivity1 = new System.Workflow.Activities.DelayActivity(); this.codeActivity1 = new System.Workflow.Activities.CodeActivity(); this.whileActivity1 = new System.Workflow.Activities.WhileActivity(); this.onWorkflowActivated1 = new Microsoft.SharePoint.WorkflowActions.OnWorkflowActivated(); // // delayActivity1 // this.delayActivity1.Name = "delayActivity1"; this.delayActivity1.TimeoutDuration = System.TimeSpan.Parse("00:05:00"); this.delayActivity1.InitializeTimeoutDuration += new System.EventHandler(this.delayActivity1_InitializeTimeoutDuration); // // codeActivity1 // this.codeActivity1.Name = "codeActivity1"; this.codeActivity1.ExecuteCode += new System.EventHandler(this.codeActivity1_ExecuteCode); // // whileActivity1 // this.whileActivity1.Activities.Add(this.delayActivity1); codecondition1.Condition += new System.EventHandler<System.Workflow.Activities.ConditionalEventArgs>(this.IsWorkFlowPending); this.whileActivity1.Condition = codecondition1; this.whileActivity1.Name = "whileActivity1"; activitybind2.Name = "Workflow1"; activitybind2.Path = "workflowId"; // // onWorkflowActivated1 // correlationtoken1.Name = "workflowToken"; correlationtoken1.OwnerActivityName = "Workflow1"; this.onWorkflowActivated1.CorrelationToken = correlationtoken1; this.onWorkflowActivated1.EventName = "OnWorkflowItemChanged"; this.onWorkflowActivated1.Name = "onWorkflowActivated1"; activitybind1.Name = "Workflow1"; activitybind1.Path = "workflowProperties"; this.onWorkflowActivated1.Invoked += new System.EventHandler<System.Workflow.Activities.ExternalDataEventArgs>(this.OnActived); this.onWorkflowActivated1.SetBinding(Microsoft.SharePoint.WorkflowActions.OnWorkflowActivated.WorkflowIdProperty, ((System.Workflow.ComponentModel.ActivityBind)(activitybind2))); this.onWorkflowActivated1.SetBinding(Microsoft.SharePoint.WorkflowActions.OnWorkflowActivated.WorkflowPropertiesProperty, ((System.Workflow.ComponentModel.ActivityBind)(activitybind1))); // // Workflow1 // this.Activities.Add(this.onWorkflowActivated1); this.Activities.Add(this.whileActivity1); this.Activities.Add(this.codeActivity1); this.Name = "Workflow1"; this.CanModifyActivities = false; } #endregion private DelayActivity delayActivity1; private WhileActivity whileActivity1; private CodeActivity codeActivity1; private Microsoft.SharePoint.WorkflowActions.OnWorkflowActivated onWorkflowActivated1; } }
相关文章推荐
- SharePoint开发学习笔记4——使用aspx自定义表单的工作流(1)
- 一步一步学习sharepoint2010 workflow 系列第三部分:自定义SharePoint代码工作流 第12章 工作流开发技巧包 (A bag of workflow developer tricks)
- SharePoint 2007工作流开发点滴(4) : 工作流中的自定义类与内部错误
- 如何在SharePoint 2010工作流开发自定义条件
- 使用自定义任务审批字段创建 SharePoint 顺序工作流
- SharePoint无代码工作流设计开发实例——交通费报销流程(二)
- 开发顺序工作流时注意的几个事项
- 开发自定义字段类型 sharepoint
- SP2010开发和VS2010专家"食谱"--第二章节--工作流(4)--创建自定义任务表单
- sharepoint 2013基于AD的Form表单登录(四)——开发自定义登录过程需要引用文件路径。
- SharePoint开发错误—列表自定义表单出现“未将对象引用设置到对象的实例”
- SharePoint开发 - 自定义导航菜单(三)附其他代码
- 开发顺序工作流时注意的几个事项
- SharePoint无代码工作流设计开发实例——交通费报销流程(一)
- SharePoint无代码工作流设计开发实例——交通费报销流程(三)
- SharePoint 2013 工作流之Visual Studio开发示例篇
- sharepoint 顺序工作流(sharepoint页面上设计工作流)
- SharePoint 2010 自定义状态机工作流 (StateMachine Workflow) + InfoPath 实例part1 (工作流实现部分)
- 开发SharePoint 自定义WebService 的小工具
- SP2010开发和VS2010专家"食谱"--第二章节--工作流(4)--创建自定义任务表单