quickflow最新版本增加了ExecuteCode活动,用Designer设计的流程也可以编写代码逻辑了。
UserContext:指定代码是以启动人的身份还是系统账号身份运行。
MethodCode:要运行的代码, 双击活动即可调出代码编辑窗口
MethodParam:参数,可以在代码中直接通过param访问。
ExecuteCode实现原理:
ExecuteCode采用动态代码编译实现,用户可以指定一个方法的实现代码,QuickFlow会把方法代码最终编译成一个类DynamicClass ,如下:
using System.Collections.Generic; using System.Linq; using System.Text; using System.Workflow.ComponentModel; using Microsoft.SharePoint; using Microsoft.SharePoint.Workflow; using Microsoft.SharePoint.WorkflowActions; using CodeArt.SharePoint.CamlQuery; //methodusing namespace DynamicCodeGenerate { public class DynamicClass : QuickFlow.DynamicClassTemplate { public DynamicClass(Activity root, SPWorkflowActivationProperties p) : base(root, p) { } protected override void Execute(string param) { //dllref //using CodeArt.SharePoint.CamlQuery; //methodcode ; } } }";
用户代码被插入到//methodcode 的位置。
基本方法
DynamicClass的基类已经实现了大量常用的方法,可以直接调用:
基本属性和方法
SPWeb Web | 获取当前SPWeb |
SPListItem Item | 获取当前ListItem |
protected SPList List | 获取当前List |
void Log(object msg) | 写日志,日志信息会显示到工作流状态页面 |
object GetVariable(string name) | 获取工作流变量值 |
void SetVariable(string name, object v) | 设置工作流变量值 |
列表项操作方法
SPListItem GetItem(string listName, int itemId) | 获取列表项 |
SPListItemCollection GetItems(string listName, CamlExpression expr) | 查询列表项 |
void UpdateItem(string fieldNames, params object[] values) | 更新列表项 |
void UpdateItem(string listName, int itemId, string fieldNames, params object[] values) | |
UpdateItem(String listName, int itemId, Hashtable properties) | |
int CreateItem(String listName, Hashtable properties) | 创建列表项 |
int CreateItem(string listName, string fieldNames, params object[] values) | |
void DeleteItem(String listName, int itemId) |
删除列表项 |
void DeleteItems(String listName, CamlExpression expr) |
删除符合条件的列表项 |
void SetModerationStatus(String listName, int itemId, SPModerationStatusType type, string comments) | 设置内容审批状态 |
void SetModerationStatus(SPModerationStatusType type, string comments) | 设置当前项目的内容审批状态 |
QuickFlow.DynamicClassTemplate 的实现见:
除了以上提供的方法,可以编写任何C#代码
注:
1)建议只在QFD中使用ExecuteCode,如果采用VS+QF,直接处理QuickFlow提供的相关事件(如Completed)或者用Step+CodeActivity更好的实现代码功能。
2)在自定义表单的情况下,代码应该优先写到表单中或业务逻辑层。
3)若需要引用其他dll或名称空间,代码格式如下:
//dllref some.dll
//using xxx.xxx;
...other code
dll需要先部署到GAC
4)引用外部dll示例:
//dllref System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
//dllref System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
//using System.Data;
//using System.Data.SqlClient;
DataTable dt = null;
5) 最新版本考虑到安全性,不允许直接通过 dllref引用外部dll,若需要引用外部程序集, 必须首先配置到web.config的<authorizedTypes>中:
<authorizedTypes>
<authorizedType Assembly="System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Namespace="*" TypeName="*" Authorized="True" />
<authorizedType Assembly="System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" Namespace="*" TypeName="*" Authorized="True" />
然后在编辑器中:
//dllref System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
//dllref System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
//using System.Data;
//using System.Data.SqlClient;
DataTable dt = null;
dllref始终是需要的,authorizedType的配置用于工作流运行时的安全校验。而dllref是为了设计时校验用的。
示例:
如何通过ExecuteCode获取其他列表数据。
场景:有个配置列表用来配置每步的审批人,配置列表字段如下:
Title: 工作流名称
Level1Approver:第一步审批人
Level2Approver:第二步审批人
操作步骤:
新建工作流,加两个string类型工作流变量:level1Approver,level2Approver
拖一个ExecuteCode活动,拖两个Task活动,task活动的User属性分别绑定到level1Approver,level2Approver。
画线连接Start->ExecuteCode-Task1->Task2.
双击ExecuteCode,写脚本如下:
QueryField titleField = new QueryField("Title");
SPList cfgList = this.Web.Lists["审批人配置"];
var cfgItem = ListQuery.From(cfgList).Where(titleField=="名片申请").GetItems()[0]; //获取到配置项
//获取字段值
SPFieldUserValue user1Value = cfgItem .Fields.GetField("Level1Approver").GetFieldValue(cfgItem["Level1Approver"].ToString()) as SPFieldUserValue;
var level1User = user1Value.User.LoginName;
this.Log("getLevel1Approver:" + level1User);
this.SetVariable("level1Approver", level1User);
//获取字段值
SPFieldUserValue user2Value = cfgItem .Fields.GetField("Level2Approver").GetFieldValue(cfgItem["Level2Approver"].ToString()) as SPFieldUserValue;
var level2User = user2Value.User.LoginName;
this.Log("getLevel2Approver:" + level2User);
this.SetVariable("level2Approver", level2User);
complete post: http://www.cnblogs.com/jianyi0115/archive/2013/05/14/3077140.html