用vs2010创建带有AssociationForm的工作流
有些情景我们需要在创建workflow的时候输入一些信息(注意:这里是创建,而不是启动)。当启动每个workflow的时候再输入一些信息。这样说可能有些抽象,举个实际例子:教导主任要找几个老师批改作业,那么就需要制定一些标准比如每道题多少分。假设一共 4 道题于是教导主任创建这个工作流的时候需要一些信息。类似这样:A 20,B 30,C 30 D 20。而每个老师接到自己的工作流实例的时候呢,就需要写上所修改卷子的分数(当然,需要参考教导主任给的标准)。所以,教导主任输入的信息是共用的,每个老师自己输入的是和所启动工作流相关的。对应到实际工作流里,教导主任和老师所输入数据的页面分别叫做 AssociationForm 和 InitiationForm。
1,首先,打开 vs2010 新建一个 sequential workflow 类型的工程(在 c# -> SharePoint 节点下)。接下来输入你想部署到的site上的url 点击next,在下一步的对话框中输入 workflow 的名字。选择 listworkflow,点击next,选择相应的list,histtorylist,tasklist.完成。
2,在刚刚创建的 workflow 的工程中添加一个 module,再添加两个 application page 分别命名为:AssociationForm.aspx, InitiationForm.aspx.(刚刚添加进去的applicationpage会被保存在layouts文件夹下,我们需要手动将两个页面拖拽到 module下面。
在这里插一段workflow附加到list上的知识介绍,一个workflow被部署到list上以后,实际上是一个模板,需要我们按照木板创建一个实例,而这个实例和list在一起叫做一个association。而我们的 associationForm是在创建一个工作流实例的时候指定的,也就是说是与一个association绑定。关于这点,从object model上也能看出来。而页面上的相关信息也需要保存,这些数据通常保存在 associationData中,这个对象附属于一个 association。
好,有了上面的基本概念,现在来看看我们的 association页面。
首先我们在页面上添加几个textBox用来给教导主任输入各个题目的分值。分别叫做txtBox1,txtBox2,txtBox3,txtBox4。明确我们要在这个页面做几件事:搜集textn的消息,并保存传递到其他工作流实例(用来给批改卷纸的老师做参考)。除此之外还要保存工作流association,即工作流和这个list的关联。(其实还有权限验证之类的在这里不做描述)。
前面讲过,association页面里的内容是所有开启的工作流实例所公用的。所以要保存在 association 的 associationData 里。大家知道,数据需要传输或者存储的话需要封装成一个对象后序列化。所以我们声明一个 class 用来封装 textn 的数据。(声明:代码等都是简化的,为了说明原理)。
class InfoData
{
private string a;
public string A{ get{return a;}set{a = value;}
// 后面的 bcd 和 a 的格式一样,这里省略。
}
既然是序列化,就需要一个序列化方法,将对象序列化成字符串。
internal string SerializeInfoToXml()
{
InfoData data = new InfoData();
data.A = txtBox1.Text;
data.B = txtBox2.Text;
data.C = txtBox3.Text;
data.D = txtBox4.Text;
using (MemoryStream stream = new MemoryStream())
{
XmlSerializer serializer = new XmlSerializer(typeof(InfoData));
serializer.Serialize(stream, data);
stream.Position = 0;
byte[] bytes = new byte[stream.Length];
stream.Read(bytes, 0, bytes.Length);
return Encoding.UTF8.GetString(bytes);
}
}
在页面里声明几个变量
protected SPWorkflowTemplate mTemplate; // 当workflow部署到 list 以后是作为一个 workflowtemplate存在的 Web 里(注意是web,不是list)
protected SPWorkflowAssociation mAssociation; // 后面将会用来把这个 association 添加到 list的 association 集合里。
而如果我们想获取相关的信息,比如说 workflowid,以及workflow的相关设置等可以从url获取。
下面罗列一下常用的数值:
工作流模板的 id : Request.Params["WorkflowDefinition"]
此模板是不是被设置成自动启动:Request.Params["AutoStartCreate"]
private void AddAssociation()
{
// 之前讲过,工作流模板是存在于web里的
SPWorkflowTemplate template = Web.WorkflowTemplates[new Guid(Request.Params["WorkflowDefinition"])];
//获取 history list id
Guid historyListGuid = Request.Params["HistoryList"];
SPList historyList = Web.Lists[historyList];
// 获取 taskListGuid
Guid taskListGuid = Request.Params["TaskList"];
SPList taskList = Request.Params[taskListGuid"];
// 获取启动方式
SPWorkflowAssociation association = SPWorkflowAssociation.CreateListAssociation(template, wfName, taskList, historyList);
association.Name = wfName;
association.AutoStartChange = (Request.Params["AutoStartChange"] == "ON");
association.AllowManul = (Request.Params["AllowManual"] == "ON");
//其他几个常用属性都有对应参数在这里不都写了
// 接下来要把 association的信息附着在 association data 上
string info = SerializeInfoToXml();
// 接下来要做的就是取出现在所在的list并把association加到list的association的集合里
string listId = Request.QueryString["List"];
SPList list = Web.Lists[new Guid(listId)];
list.WorkflowAssociations.Add(association);
}
3,修改workflow 的element的associationFormUrl属性,改成相应的url.
好了,这样一个 association 就创建好了,而且还具有一个associationForm用来搜集对以这个关联创建的workflow来说是全局的数据。