有些情景我們需要在創建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 www.2cto.com
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來說是全局的數據。
作者:雨夜孤鶴