用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来说是全局的数据。

 

http://www.cnblogs.com/liyunbo

posted @ 2011-11-30 19:36  Areas  阅读(279)  评论(0编辑  收藏  举报