QuickFlow教程(9)—Step Modification in QF Designer

来源:互联网 发布:chantelle sydney知乎 编辑:程序博客网 时间:2024/05/18 03:58

在Build100316之前的版本中,QF的Step Modification只支持VS2008+QF的情况。如果用QFD的时候添加了EnableStepModification活动,则工作流状态页面会报错。查询了一下资料,最终发现SharePoint Designer设计的无代码工作流不支持Modification,而QFD跟SharePoint Designer设计工作流的原理是一样的,所以QFD设计的工作流添加Modification功能也是不被SharePoint支持的。

但是理论上来说,无代码工作流跟VS2008设计的有代码工作流原理是一样的。为什么VS2008设计的可以,而SPD和QFD设计的就不可以呢?

打开WrkStat.aspx页面,可以找到出错的代码:

foreach (DictionaryEntry entry in Modifications)
        {
            SPWorkflowModification mod = (SPWorkflowModification)entry.Value;
            WorkflowModString = (string)WTBase["Modification_" + mod.Id.ToString() + "_Name"];

这几行代码循环工作流启用的所有Modification,然后用ModificationID获取相应的名称。在用VS2008启用Modification的时候,workflow.xml内容如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<Elementsxmlns="http://schemas.microsoft.com/sharepoint/">
  <Workflow
     Name="QFExamples_StepMod"
     Description="My SharePoint Workflow"
     Id="f5b50d75-85da-48d3-9775-2616c3caea4b"
     CodeBesideClass="QFExamples_StepMod.Workflow1"
     CodeBesideAssembly="QFExamples_StepMod, Version=1.0.0.0, Culture=neutral, PublicKeyToken=dc008f2bb43d9b78"     
     <STRONG>ModificationUrl="_layouts/QuickFlow/WrkMod.aspx"</STRONG>
    >     
  
    <Categories/>
    <MetaData>    
  
      <STRONG><Modification_93a2410e-8590-44c2-a6cd-4ef60347b380_Name>Step Mod</Modification_93a2410e-8590-44c2-a6cd-4ef60347b380_Name></STRONG>      
      <StatusPageUrl>_layouts/WrkStat.aspx</StatusPageUrl>      
  
    </MetaData>
  </Workflow>
</Elements>

WTBase["Modification_" + mod.Id.ToString() + "_Name"]既是获取Modification_93a2410e-8590-44c2-a6cd-4ef60347b380_Name中的内容。

那么,在用无代码工作流的情况下,workflow.xml是没有的,强制启用了Modification,就出错了。

而通过跟踪WrkStat.aspx中Modifications的值,在用QFD而启用了StepModification的情况下,发现Modifications中是有相应的数据的,那么,很显然,通过修改WrkStat.aspx的内容,是有可能让QFD和SPD设计的无代码工作流支持Modification的。

最终,将WrkStat.aspx的内容修改如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
           if(allowModifications)
{
string WorkflowModString = "";              
foreach(DictionaryEntry entryinModifications)
{
    SPWorkflowModification mod = (SPWorkflowModification)entry.Value;
    try{
        WorkflowModString =""+WTBase["Modification_"+ mod.Id.ToString() + "_Name"];//may be empty
 
    }catch{} 
    // get mod name and url form mod context
    if(string.IsNullOrEmpty(WorkflowModString) &&string.IsNullOrEmpty(ModificationUrl))
    {
        if(!String.IsNullOrEmpty(mod.ContextData))
        {
            Response.Write(mod.ContextData);
            string[] arr = mod.ContextData.Split(',');
            if(arr.Length == 2)
            {
                WorkflowModString = arr[0];
                ModificationUrl = arr[1];
            }
            else
            {
                continue;
            }
        }
        else
        {
            continue;
        }
    }               
      
    stringWorkflowModUrl = Web.Url +"/"
                        + ModificationUrl
                        +"?ID="+ ListItem.ID
                        +"&List="+ Request.QueryString["List"]
                        +"&WorkflowInstanceID="+ StrGuidWorkflow
                        +"&Source="+ SPHttpUtility.UrlKeyValueEncode(Request.RawUrl);
 
    stringWorkflowModUrlWithSub = WorkflowModUrl +"&ModificationID="+ mod.Id.ToString();
系统默认的实现完全是通过workflow.xml获取Modification Name和ModificationUrl,而以上代码通过

SPWorkflowModification的ContextData属性获取到Modification Name和ModificationUrl。

ContextData的初始化在EnableStepModification中处理:

?
1
2
3
4
5
this.enableWorkflowModification1.MethodInvoking +=newSystem.EventHandler(this.enableMod_Invoking);
privatevoidenableMod_Invoking(objectsender, EventArgs e)
       {
           ContextData ="step modification,_layouts/QuickFlow/WrkMod.aspx";
       }
最后经过测试,这个方案是完全可行的---QFD的最新版本已经支持步骤的管理,而且比VS2008+QF的实现更简单。只要拖拽

EnableStepModification到设计器上即可:

image

image

本文中的功能,需要QF Build100320,QFD Build100323以上版本支持。

http://quickflow.codeplex.com/

 

备注:

本文中阐述的解决方案修改了系统默认页面,在安装最新的QF wsp时会自动给覆盖WrkStat.aspx页面, 如果发现本文的解决方案跟其他MOSS+WF场景冲突,可以将layouts目录下的WrkStat_bak.aspx页替换WrkStat.aspx页面,WrkStat_bak.aspx为原始系统页面的备份。

 

转自:http://www.cnblogs.com/jianyi0115/archive/2010/03/20/1690566.html

 
 
我的备注:
1.如果想自己完成step Modification功能,可以用如下方式实现:

SPListItem item = list.GetItemById(ID);

                for (int m = 0; m < item.Workflows.Count; m++)
                {

                    string result = item.Workflows[m].InternalState.ToString();  //获取工作流状态
                    if (result.Trim().Equals("Running"))
                    {

                              var flow = item.Workflows[m];  //多流程中的其中一个
                                //flow.StopWorkflow();  //停止工作流
                             flow.ModifyWorkflowStep("stepName");  //修改工作流到某一步stepName

 

                    }

 
2.如果自定义网页,需要使用到sharepoint step Modification的页面,step Modification路径拼接方式:

 string opraGuid = e.CommandArgument.ToString().Trim();

                    //封装撤回的URL
                    string gotoUrl = "http://xxx.xx.xx.xx:8080/_layouts/QuickFlow/WrkMod.aspx?";
                    //string gotoUrl = "http://localhost:8080/_layouts/QuickFlow/WrkMod.aspx?";  //测试

                    #region url格式
                    //http://localhost:8080/_layouts/QuickFlow/WrkMod.aspx?ID=3&List=0b700a0f-b48d-40ec-8fe9-1d12f06fdfdf&WorkflowInstanceID={8F73BEB6-D709-46CB-AD20-256F6C5DF2F1}&Source=%2F%5Flayouts%2FWrkStat%2Easpx%3FList%3D%7B0B700A0F%2DB48D%2D40EC%2D8FE9%2D1D12F06FDFDF%7D%26WorkflowInstanceID%3D%7B8F73BEB6%2DD709%2D46CB%2DAD20%2D256F6C5DF2F1%7D&ModificationID=93a2410e-8590-44c2-a6cd-4ef60347b380
                    #endregion

                    #region 数据处理

                    SPList wfList = web.Lists["listName"];
                    SPQuery query = new SPQuery();
                    query.Query = @"<Where>
                              <Eq>
                                 <FieldRef Name='Guid0' />
                                 <Value Type='Text'>" + opraGuid + @"</Value>
                              </Eq>
                           </Where>";
                    query.ViewAttributes = "Scope=\"RecursiveAll\"";
                    SPListItemCollection itemcol = wfList.GetItems(query);
                    SPListItem item = itemcol[0];

                    string itemID = item.ID.ToString().Trim();
                    string wflistGuid = wfList.ID.ToString().Trim();
                    string workflowInstanceID = "";


                    if (item["WorkflowStep"] != null && item["Status"].ToString().Trim().Equals("1"))
                    {

                        //Workflows.Count==1
                        for (int m = 0; m < item.Workflows.Count; m++)
                        {
                            string result = item.Workflows[m].InternalState.ToString();
                            if (result.Trim().Equals("Running"))
                            {
                                var flow = item.Workflows[m];
                                workflowInstanceID = flow.InstanceId.ToString().Trim();
                            }

                        }

                        string sourceList = wflistGuid.Replace("-", "%2D").ToUpper();
                        string sourceWorkflowInstanceID = workflowInstanceID.Replace("-", "%2D").ToUpper();
                        string sourceUlr = "%2F%5Flayouts%2FWrkStat%2Easpx%3FList%3D%7B" + sourceList + "%7D%26WorkflowInstanceID%3D%7B" + sourceWorkflowInstanceID + "%7D&ModificationID=93a2410e-8590-44c2-a6cd-4ef60347b380";

                        gotoUrl += "ID=" + itemID + "&List=" + wflistGuid + "&WorkflowInstanceID={" + workflowInstanceID + "}&Source=" + sourceUlr;

                        Page.ClientScript.RegisterStartupScript(GetType(), "撤回", "<script language='javascript'>window.location.href='" + gotoUrl + "'</script>");