混合OOTB SPD WFA和自定义WFA的问题

时间:2011-06-24 20:48:58

标签: sharepoint sharepoint-2007 workflow sharepoint-workflow

我正在使用MOSS(SharePoint 2007 Enterprise),32位,SP2。

我一直注意到自定义工作流活动的一些奇怪问题,我已经开发并在SharePoint Designer(SPD)工作流程中使用。这些操作似乎工作正常,但不要与工作流的其余部分“玩得很好”(具体来说,根问题发布在:Timing concerns with Custom WF Activity changing permissions,因为这没有得到我一直在挖掘的任何响应更深...)

为了帮助解决问题,我开发了一个非常简单的测试,我将在下面详细介绍,并注意到这个测试更奇怪的行为,这是我将首先进入的...

所以,在这个测试结束时,我有一个简单的SPD WF,我可以在我为此测试创建的列表上手动启动,该列表包含名为“TextField”的单行文本字段/列。 WF包含1个步骤,执行4个操作:

  1. 将字段设置为值(使用我的自定义WFA将“1”分配给TextField列)
  2. 将“设置1”记录到工作流程历史记录列表
  3. 在当前项目中设置字段(使用OOTB操作将“2”分配给TextField列)
  4. 将“Set 2”记录到工作流程历史记录列表
  5. 此工作流程运行良好,按顺序成功完成工作流消息,TextField == 2。

    但是,如果我将最后2个动作移到动作列表的顶部,那么使WF单步执行如下操作:

    1. 在当前项目中设置字段(使用OOTB操作将“2”分配给TextField列)
    2. 将“Set 2”记录到工作流程历史记录列表
    3. 将字段设置为值(使用我的自定义WFA将“1”分配给TextField列)
    4. 将“设置1”记录到工作流程历史记录列表
    5. 在这种情况下,工作流状态为“发生错误”,即使TextField == 1(第二个分配),工作流历史记录中的唯一项目是:

      1. 更新列表项时出错
      2. 设置字段测试中发生错误。
      3. (“设置字段测试”是我的SPD WF的名称)

        所以,这就是问题所在:如果我的自定义WFA首先发生,WF可以100%工作,但如果我的自定义WFA发生第二次,则每次都会失败(即使字​​段确实正确更新)。我多次重复这个测试,包括多次执行动作反转。

        我可能在我的自定义WFA中做了一些愚蠢的事情,所以在这里(我已经用公共机构取代了我公司的首字母缩略词 - 获得我的税收资金):

        using System;
        using System.ComponentModel;
        using System.ComponentModel.Design;
        using System.Collections;
        using System.Drawing;
        using System.Reflection;
        using System.Workflow.ComponentModel;
        using System.Workflow.ComponentModel.Design;
        using System.Workflow.ComponentModel.Compiler;
        using System.Workflow.ComponentModel.Serialization;
        using System.Workflow.Runtime;
        using System.Workflow.Activities;
        using System.Workflow.Activities.Rules;
        using Microsoft.SharePoint;
        using Microsoft.SharePoint.Workflow;
        
        namespace NASA.workflowActivity {
        public partial class TestSetFieldValueActivity : Activity {
        
            #region Dependency Properties
        
                public static DependencyProperty itemFieldProperty = DependencyProperty.Register("itemField", typeof(String), typeof(TestSetFieldValueActivity));
        
                public static DependencyProperty newValueProperty = DependencyProperty.Register("newValue", typeof(String), typeof(TestSetFieldValueActivity));
        
                public static DependencyProperty __ActivationPropertiesProperty = DependencyProperty.Register("__ActivationProperties", typeof(Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties), typeof(TestSetFieldValueActivity));
        
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
                [ValidationOption(ValidationOption.Required)]
                [Browsable(true)]
                public String itemField {
                    get { return base.GetValue(TestSetFieldValueActivity.itemFieldProperty).ToString(); }
                    set { base.SetValue(TestSetFieldValueActivity.itemFieldProperty, value); }
                }
        
                [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
                [ValidationOption(ValidationOption.Required)]
                [Browsable(true)]
                public String newValue {
                    get { return base.GetValue(TestSetFieldValueActivity.newValueProperty).ToString(); }
                    set { base.SetValue(TestSetFieldValueActivity.newValueProperty, value); }
                }
        
                [ValidationOption(ValidationOption.Required)]
                public Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties __ActivationProperties {
                    get { return (Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties)base.GetValue(TestSetFieldValueActivity.__ActivationPropertiesProperty); }
                    set { base.SetValue(TestSetFieldValueActivity.__ActivationPropertiesProperty, value); }
                }
        
            #endregion
        
            protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext) {
                try {
                    SPListItem listItem = this.__ActivationProperties.Item;
                    SPField field = listItem.Fields[this.itemField];
                    listItem[field.Id] = this.newValue;
                    listItem.SystemUpdate();                
                } catch {
                    return ActivityExecutionStatus.Faulting;
                }
                return ActivityExecutionStatus.Closed;
            }
        
        }
        }
        

        我的.ACTIONS文件(保存到C:\ Program Files \ Common Files \ Microsoft Shared \ web服务器扩展\ 12 \ TEMPLATE \ 1033 \ Workflow)包含此操作的条目:

        <Action 
                    Name="Set field in current item (Custom WFA)"
                    ClassName="NASA.workflowActivity.TestSetFieldValueActivity"
                    Assembly="NASA.workflowActivity, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f579ebeb24170bf5"
                    AppliesTo="all"
                    Category="NASA WFA: Test">
                <RuleDesigner Sentence="Set %1 to %2 (Custom WFA)">
                    <FieldBind Id="1" Field="itemField" DesignerType="FieldNames" text="field" />
                    <FieldBind Id="2" Field="newValue" DesignerType="Text" text="value" />
                </RuleDesigner>
                <Parameters>
                    <Parameter Name="itemField" Type="System.String, mscorlib" Direction="In" />
                    <Parameter Name="newValue" Type="System.String, mscorlib" Direction="In" />
                    <Parameter Name="__ActivationProperties" Type="Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties, Microsoft.SharePoint" Direction="In" />
                </Parameters>
            </Action>
        

        最后,当然,我的web.config包含了我的程序集的条目。

        这当然是一个非常简单的动作,但即使也无法在我的SPD WF中正常工作。我一定做错了,但是我在创建自定义WFA时可以找到的所有文档都让这看起来不错。任何人都可以在我的代码中看到问题,甚至可以在您自己的环境中尝试这个问题吗?

1 个答案:

答案 0 :(得分:1)

我在开源项目中已经解决了这个问题。从http://spdactivities.codeplex.com/下载源代码,并查看其中一个权限活动的来源。您的代码不起作用的原因是因为OOTB活动参与了事务而您的自定义活动没有。这就是您的自定义活动在所有OOTB活动之前运行的原因。

要参与工作流程,您需要实施IPendingWork并提交至WorkflowEnvironment.WorkBatch。 HTH