2011-06-24 21 views
1

我正在使用MOSS(SharePoint 2007 Enterprise),32位SP2。混合OOTB SPD WFA和自定义WFA的问题

我一直注意到我开发并在SharePoint Designer(SPD)工作流中使用的自定义工作流活动中的一些奇怪问题。这些操作看起来可以正常工作,但不要与其他工作流程“发挥不错”(具体来说,根问题发布在:Timing concerns with Custom WF Activity changing permissions,因为这还没有得到任何我深入挖掘的答案...... )

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

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

  1. 将字段设置为Value(使用我的自定义WFA分配“1”的文本字段列)
  2. 登录“设置1”工作流历史记录列表
  3. 集场当前项目(使用开箱即用的操作将其分配“2”的文本字段列)
  4. 登录“设置2”工作流历史记录列表

此工作流完美运行,与工作流成功完成消息按顺序排列,a nd TextField == 2。

然而,如果我将最后2个动作来操作列表的顶部,使得那么WF的一个步骤是这样的:

  1. 集场当前项目(使用开箱即用的操作将其分配“2”的文本字段列)
  2. 登录“设置2”工作流历史记录列表
  3. 将字段设置为Value(使用我的自定义WFA分配“1”的文本字段列)
  4. 登录“设置1 “到工作流历史列表

在这种情况下,工作流状态为“出错”,即使文本字段== 1(第二分配)工作流历史上唯一的项目有:

  1. 错误更新列表item
  2. Set Field Test中发生错误。

(“设置现场测试”是我的SPD WF的名称)

所以,这就是问题的样子:在WF工程100%,如果我的自定义WFA首先发生,但无法每次(即使该字段没有正确更新)如果我的自定义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共享\ web服务器extensions \ 12 \模板\ 1033 \工作流)包含此项此动作:

<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

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

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

+0

我之前已经找到了您的解决方案(感谢在Codeplex上共享源代码),但是当我实现IPendingWork并在那里执行我的现场更新时,该更新总是在工作流中发生。从我上面的示例WF中,我得到了一个WF历史记录,正确地说明了“设置'1'(自定义),然后设置'2'(OOTB)”,但是该字段将被设置为'1',并且如果我写入历史在我的代码列表中,那么这条消息将是第三。你需要以某种方式使用Commit()中的Transaction obj吗?我没有看到它在你的代码中被使用。 – DaveD