zoukankan      html  css  js  c++  java
  • QuickFlow教程(15)常见问题释疑

    本文将针对QuickFlow开发人员经常碰到的问题做一个集中的解释。

    1)QuickFlow是什么

    QuickFlow是基于SharePoint(2007,2010)的一个工作流设计工具,它包含一个核心的Flowchart流程模型和一个无代码设计器。基于QuickFlow开发SharePoint工作流和直接在SharePoint上开发工作流很类似,使用Quickflow前最好了解下默认的SharePoint工作流是如何开发和运行的。

    更多细节,参见:http://cid-7f5a25cdf47d03e6.office.live.com/view.aspx/QuickFlow/Docs/QuickFlow2.0%E7%99%BD%E7%9A%AE%E4%B9%A6.docx

    2)QuickFlow如何安装

    QuickFlow的安装包含两部分:一部分是一个wsp的解决方案,这个解决方案中,包括所有dll文件和页面文件,这个wsp分两个版本:一个用于SharePoint2007,一个用户SharePoint2010。另外一部分是设计器,设计器无需安装,直接解压后即可打开exe文件,需要指出的是,当前版本的设计器只能在SharePoint服务器上运行。

    详细见:http://cid-7f5a25cdf47d03e6.office.live.com/view.aspx/QuickFlow/Docs/QuickFlow%E5%AE%89%E8%A3%85%E6%8C%87%E5%8D%97.docx

    3)Quickflow使用中碰到错误如何解决

    有几种类型的错误:

    发布流程时:这个时候出错,一般是web.config配置错误,重新激活下QuickFlow feature即可。在SP07下,在网站集功能管理中操作,在SP10下,需要到管理中心激活QuickFlow App Configuration feature,详见安装文档

    工作流运行时:有很多种可能性,首先要找到日志信息,日志有两个地方可以看,一个是工作流状态页面--在列表页面,点击工作流链接进入。在这个页面可以看到QuickFlow内部输出的日志。不仅仅是碰到错误,如果工作流没错误,但是运行结果跟预期的不一致,也可以到这个页面查看信息。比如设置了发送邮件,但是测试时却没有收到,那么状态页面会记录邮件发现情况。

    另一个查看日志的地方是12/Logs or 14/Logs目录,这是SP自带的日志文件。打开最新的日志文件,在里面搜索Workflow Infrastructure ,可以搜到跟工作流有关的日志信息。

    注:日志目录[C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\LOGS]

    在页面提交的时出错: 这个时候,如果发现页面上没有详细的错误信息,那么首先要让SP显示出详细错误,这个操作是SP开发第一步就要做的。详细:google SharePoint 详细错误。 需要指出的是:Layouts下的web.config也是需要修改的(set customError mode=’off’)

    4)关于工作流变量(workflow variable)

    工作流变量是当使用QuickFlow Designer时,允许在流程级别添加一些特定类型的字段,各个活动的属性可以跟工作流变量绑定,UI代码可以直接控制工作流变量的值。

    如果您是用VisualStudio+QuickFlow开发,那么是没必要用工作流变量的,工作流变量其实是模拟添加类字段(field)。用vs时,可以很方便的在工作流中添加字段,为什么还要用工作流变量呢?

    当然,vs中工作流变量还是可以使用的,那么一般会碰到两个问题:

    a)如何在UI代码中控制工作流字段的值:跟控制工作流变量的值是一样的,用QuickFlow.Core.WorkflowContext.Current.UpdateWorkflowVariable("NextApprovors", nextUsers);

    b)如何在WF代码中控制工作流变量的值:直接设置字段的值即可,或者,用base.UpdateVariable("NextApprovors", nextUsers);如:

    public QuickFlow.NameCollection nextUsers ;
    //nexUsers bind to multiTask.Users
    private void task_init(object sender, EventArgs e)
    {
    this.nextUsers = ...;

    //or base.UpdateVariable("nextUsers", nextUsers);
    }

    记住:

    在用VS+QF时,工作流变量跟普通的字段是一样的。
    永远不要在VS的WF代码中调用WorkflowContext.Current。

    如果要在UI代码中传递变量值,只能在几个固定的事件方法中才可行:

    1-StartWorkflowButton.Executing事件中,

    2-ActionsButton.ActionExecuting事件中,

    3-TaskReassignButton.Executing事件中,

    4-在启动页面或任务页面的Page_Load事件中,Page_Load中给工作流变量赋值后,必须在以下的操作中启动工作流或提交任务才会有效

    无论在哪个方法中,都需要使用QuickFlow.Core.WorkflowContext.Current.UpdateWorkflowVariable来更新变量

    注意:在UI代码中,只能设置工作流变量的值而不能获取工作流变量值,如果碰到必须获取工作流变量的情况,那么可以用列表字段传值来实现。

    5)关于WorkflowContext.Current

    这个类用于在工作流页面中跟工作流交互。非工作流页面不能使用。

    6)如果不用QuickFlow提供的控件来开发工作流页面,如何启动流程,提交任务呢?

    有两种方式:

    a)直接用SharePoint的对象模型来操作。这样做会有些复杂性。

    跟Workflow有关的方法有:SPSite.WorkflowManager.StartWorkflow, SPWorkflow.AlterTask,详细见SharePoint SDK.

    b)用QuickFlow提供的API操作: WorkflowContext.Current.

    用WorkflowContext.Current必须在特定的上下文下运行,包括列表的新建页面,任务的提交页面。

    常用WorkflowContext方法如下:

    WorkflowContext.Current 获取到当前的工作流上下文
    WorkflowContext.CreateContext(SPList dataList) 基于某个列表创建一个上下文, 这样创建的context,自动工作流的时候,会自动在列表中新建一个列表项,用于非NewForm页面上启动工作流
    .DataFields[] 获取或设置列表字段值。
    .UpdateWorkflowVariable(string name, object value) 工作流启动前或任务提交前更新工作流变量
    .StartWorkflow(string wfName) 启动工作流

    .CommitTask( string outcome )

    完成任务,指定任务的结果(通过,拒绝)
    .ReAssignTask(string to) 转发任务
    WorkflowContext.Current.Task 获取当前的WorkflowTask(只能获取到上次的数据)
    WorkflowContext.Current.TaskFields["field name"] 获取当前的任务字段属性,可以获取到最新数据

    提交任务需要用WorkflowTask类

    WorkflowTask一般通过WorkflowContext.Current.Task(任务页面代码)或者WorkflowTask.FromListItem(任何地方)获取

    常用WorkflowTask方法如下:

    WorkflowTask.FromListItem  将任务Item转换成WorkflowTask类
    .Actions 获取到任务的动作集合(TaskActions)
    bool CanCommit() 当前用户是否可以提交工作流(只有网站集管理员或者任务操作人才能提交任务)
    CommitTask(string outcome) 提交任务
       

    示例:

    在列表的Newform页面启动工作流:

    WorkflowContext.Current.StartWorkflow(“My Workflow”)

    无论是启动工作流还是提交任务前,都可以传递工作流变量

    WorkflowContext.Current.UpdateWorkflowVariable(“vabiableName”,value)

    在一个普通的aspx页面启动流程(非NewForm页面):

                 var wflist = SPContext.Current.Web.Lists[“List1”];

                  WorkflowContext wfCtx = WorkflowContext.CreateContext(wflist);

                  wfCtx.DataFields["Title"] = proj.ProjectName; //设置列表项字段
                  wfCtx.DataFields["ReferenceNo"] = proj.ReferenceNo;
                  wfCtx.DataFields[ProjectID_FieldName] = proj.ID;

                  wfCtx.UpdateWorkflowVariable("sendToPCController", true);//设置工作流变量
                  wfCtx.UpdateWorkflowVariable("PCController", new NameCollection(pcController));
                  wfCtx.UpdateWorkflowVariable("PM", new NameCollection(proj.ProductManager));
                  wfCtx.StartWorkflow(Config.WorkflowName);

    在任务页面获取任务动作:

    TaskActionCollection actons = WorkflowContext.Current.Task.Actions;

    在任务页面完成任务:

    WorkflowContext.Current.CommitTask(“Approved”); //Approved is a taskAction

    在非任务页,如控制台或TimerJob代码中完成任务:

    var taskItem = taskList.GetItemById(100);
    var task = WorkflowTask.FromListItem(taskItem);
    if(task.Actoins.Count>0)  task.Commit(task.Actions[0]); 
    else taks.Commit();

    7)CommentTaskField这个富文本框能否去掉其样式呢,就是不希望用户在审批意见里添加各种样式,只要输入文字意见好了

    在网站内容类型管理中,找到任务内容类型,设置其 描述字段 不使用富文本

    8)在Initialized事件中设置了活动的属性,为什么不起作用?

    因为QF中的活动可以无限次执行,所以实际执行的活动只是设计器上的活动的副本

    如果在活动已经开始执行了,再设置设计器上的活动的属性,可能就无效了。

    有两个方法解决这个问题:

     1--事件参数sender始终是执行中的活动,直接给sender赋值,如: ((Task)sender).User = "someUserAccount";

     2--如果要让一个属性可以在活动执行时可以被修改,那么可以把这个属性绑定到一个全局变量,这样--就始终可以修改了.

     3--在这个活动前面一个活动的Completed事件中给这个活动的字段赋值。
    9)设置了规则引擎(BeforeRule or AfterRule),发现工作流长时间不结束

    原因:规则的计算,改变了规则的条件,造成规则引擎重新运行规则(造成无限循环)

    解决:把 重新计算 选项改成 永不(Never) ,  了解WF规则引擎:http://msdn.microsoft.com/zh-cn/library/aa480193.aspx

    10)任务被锁定,即使更正了代码错误,任务依然无法重新提交

    解决:需要先把任务解锁,然后重新提交即可:

    ServerModel code:

    using (SPSite site = new SPSite("http://localhost"))
                {
                    using (SPWeb web = site.OpenWeb())
                    {
                        SPList taskList = web.Lists["Tasks"];
                        var item = taskList.GetItemById(188); //change 188 to the task id
                        web.AllowUnsafeUpdates = true;
                        item[SPBuiltInFieldId.WorkflowVersion] = 1;
                        try
                        {
                            item.SystemUpdate();
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.ToString());
                        }
                    }
     }
    

    ClientModel code:

    try
    {
    using (ClientContext clientContext =new ClientContext("http://localhost"))
    {
    Web site
    = clientContext.Web;
    var list
    = site.Lists.GetByTitle("Tasks");
    ListItem item
    = list.GetItemById(188);
    clientContext.Load(item);
    clientContext.ExecuteQuery();
    Console.WriteLine(
    "WorkflowVersion: "+ item["WorkflowVersion"]);
    item[
    "WorkflowVersion"] =1;
    item.Update();
    clientContext.ExecuteQuery();
    }
    }
    catch (Exception e)
    {
    Console.WriteLine(e.ToString());
    }
    Console.WriteLine(
    "done");
    Console.ReadKey();

    注:最新版本任务被锁定后,默认任务页面上会显示一个解锁的链接,如果是自定义的页面,则在页面上加上UnLockTaskLink控件即可。

    若解锁后依然无法提交,则重新启动SharePoint Timer服务和数据库服务,然后再次解锁提交.若依然不行,则只能重启工作流。

    ref:http://connect.nintex.com/forums/thread/6503.aspx

    11)不用QuickFlow的API启动流程,而直接用纯MOSS接口启动,如何传递工作流变量呢?

    代码入下:

    //using QukckFlow.Core;

    WorkflowVariableValues vs = new WorkflowVariableValues();

    vs["variableName1"] = "value1";

    vs["variableName2"] = "value2";

    var eventData = SerializeUtil.Serialize(vs);

    SPSite site = SPControl.GetContextSite(HttpContext.Current);

    var wfName = "some workflow name";

    var wfAss =  list.WorkflowAssociations.GetAssociationByName(wfName, System.Globalization.CultureInfo.CurrentCulture);

    wf = site.WorkflowManager.StartWorkflow(listItem, wfAss, eventData);

    如果要异步启动工作流,可以调用:

    site.WorkflowManager.StartWorkflow(object context, SPWorkflowAssociation association, string eventData, SPWorkflowRunOptions runOptions)

    此异步方法只有SP2010支持。

    12)如果工作流设置成自动启动(Auto), 用StartWorkflowButton启动工作流时会报错。

    首先搞清楚MOSS默认的工作流机制:工作流启动分3种模式:

    1)手工启动--就是通过下拉菜单进入工作流启动页面启动

    2)自动启动--创建一条Item后自动自动

    3)当Item的某个字段值改变后启动

    用了StartWorkflowButton时,StartWorkflowButton会调用moss api启动工作流,实际上是模拟手工启动

    如果配置成自动自动,那么moss会自动启动一个工作流, StartWorkflowButton会再次启动一个工作流

    而一个工作里是不能启动2次的,所以,StartWorkflowButton启动工作流的时候就出错了

    所以,用了StartWorkflowButton,或用其他方式调用MOSS API启动工作流,工作流必须设置成手工启动(Manual)
     

    13)SP10任务表单上的任务历史记录列表会显示一个复选框,如何取消?

    修改任务列表的默认视图设置,取消:Allow individual item checkboxes  复选框 
     

    14)在QFD中新建了一个工作流变量,但是在活动属性绑定窗口或规则编辑窗口无法找到这个变量

    点下保存按钮,将工作流保存下即可。
     

    15)重新发布流程后,流程名称后面出现 (1)

    问题原因:是因为老版本的QFD发布流程时流程配置文件的BaseID会变造成的

    解决方法:升级到最新版本的QFD,然后用SharePoint Designer打开工作流文件夹,把.xoml.wfconfig.xml的除1.0版本和当前版本外的版本删除,

    然后将最新版本.xoml.wfconfig.xml中的BaseID修改成和1.0版本一致),用QFD重新发布流程即可

    16)如何控制WorkflowHistory/TaskList显示的字段

    如果是在自定义任务表单中,可以通过WorkflowHistory控件的ViewFields控制,如:

    <QFL:WorkflowHistory runat="server" ID="hisList"  ShowTaskOfCurrentWorkflow="true"

     ViewFields=""Title,AssignedTo, Status, Body, StartDate, WorkflowOutcome, DelegateFrom"/>

    如果是想控制QF自带的TaskList页面,则到网站设置->网站栏管理,将需要显示的字段添加到QuickFlow组中即可。

     17)RuleDriven/TaskWizard设置了超时规则,不起作用
     1-重启iis,重启SharePoint Timer服务,重启服务器

     2-设置定时job扫描间隔: stsadm -o setproperty -propertyname "job-workflow" -propertyvalue "every 2 minutes  between 0 and 59" -url http://dc

     3- 参考:http://www.dev4side.com/community/blog/2010/12/1/bug-using-delay-activity-on-sharepoint-2010-workflow.aspx

     18)采用VS+QF开发工作流时,若已经在生产环境部署,如何更新,才能保证老流程正常运行下去?

    若只是修改了方法内部的代码,则正常更新dll或wsp即可。

    若增删了活动或变量,则必须先手工备份老程序集,然后将程序集版本升版,更新新程序集或wsp,然后重新部署老程序集,确保新老程序集在gac中同时存在

    see:  http://spmat.blogspot.com/2010/11/assembly-versioning-for-sharepoint.html

     19)若发布流程时报QuickFlow or SystemXXX没有授权

    认真阅读安装指南,重新激活QuickFlow App Configuration功能

  • 相关阅读:
    1144 The Missing Number (20分)
    1145 Hashing
    1146 Topological Order (25分)
    1147 Heaps (30分)
    1148 Werewolf
    1149 Dangerous Goods Packaging (25分)
    TypeReference
    Supervisor安装与配置()二
    谷粒商城ES调用(十九)
    Found interface org.elasticsearch.common.bytes.BytesReference, but class was expected
  • 原文地址:https://www.cnblogs.com/jianyi0115/p/2078774.html
Copyright © 2011-2022 走看看