在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到设计器上即可:
本文中的功能,需要QF Build100320,QFD Build100323以上版本支持。
http://quickflow.codeplex.com/
备注:
本文中阐述的解决方案修改了系统默认页面,在安装最新的QF wsp时会自动给覆盖WrkStat.aspx页面, 如果发现本文的解决方案跟其他MOSS+WF场景冲突,可以将layouts目录下的WrkStat_bak.aspx页替换WrkStat.aspx页面,WrkStat_bak.aspx为原始系统页面的备份。