在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内容如下:

<Elements xmlns="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"     
     ModificationUrl="_layouts/QuickFlow/WrkMod.aspx"
    >     

    <Categories/>
    <MetaData>    

      <Modification_93a2410e-8590-44c2-a6cd-4ef60347b380_Name>Step Mod</Modification_93a2410e-8590-44c2-a6cd-4ef60347b380_Name>      
      <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的内容修改如下:

                   if (allowModifications)
		{
		string WorkflowModString = "";				
		foreach (DictionaryEntry entry in Modifications)
		{
			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;
                }
            }				
            
            string WorkflowModUrl = Web.Url + "/"
								+ ModificationUrl
								+ "?ID=" + ListItem.ID
								+ "&List=" + Request.QueryString["List"]
								+ "&WorkflowInstanceID=" + StrGuidWorkflow
								+ "&Source=" + SPHttpUtility.UrlKeyValueEncode(Request.RawUrl);

			string WorkflowModUrlWithSub = WorkflowModUrl + "&ModificationID=" + mod.Id.ToString();
系统默认的实现完全是通过workflow.xml获取Modification Name和ModificationUrl,而以上代码通过

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

ContextData的初始化在EnableStepModification中处理:

 this.enableWorkflowModification1.MethodInvoking += new System.EventHandler(this.enableMod_Invoking);
 private void enableMod_Invoking(object sender, 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为原始系统页面的备份。

posted on 2010-03-20 17:50  jianyi  阅读(1673)  评论(30编辑  收藏  举报