【问题标题】:How to get the context item in Workflow activity (SharePoint)如何在工作流活动 (SharePoint) 中获取上下文项
【发布时间】:2013-07-02 06:03:12
【问题描述】:

我正在为共享点工作流编写自定义活动,但我不知道如何使用当前的工作流项、SPWeb 或 SPSite。

我看到了http://blogs.microsoft.co.il/blogs/davidbi/archive/2008/07/21/How-to-get-the-context-item-in-workflow-activity-sharepoint.aspx,但是这个解决方案的 xml 例程对我来说太糟糕了。

也许还有另一种纯代码解决方案来获取工作流活动中的上下文项?

【问题讨论】:

  • 我按照这里的描述做了所有事情,但我的上下文也总是空的。我正在编写基于 SequenceActivity 的自定义 SPDesigner Activity。更重要的是,当我尝试在 Sharepoint Designer 中编辑 WF 时,由于出现错误而无法保存。

标签: sharepoint


【解决方案1】:

这个问题的答案是几个步骤:

  1. 将属性添加到您的自定义活动 .cs
  2. 链接 .actions 文件中的属性(以便 SPD 知道如何映射到您的属性)
  3. 在代码中使用属性

第 1 步:这是属性的代码(我的课程名为 GetEmails,您需要将其重命名为您的课程):

public static DependencyProperty __ContextProperty = System.Workflow.ComponentModel.DependencyProperty.Register("__Context", typeof(WorkflowContext), typeof(GetEmails));

[Description("The site context")]
[Category("User")]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public WorkflowContext __Context
{
    get
    {
        return ((WorkflowContext)(base.GetValue(GetEmails.__ContextProperty)));
    }
    set
    {
        base.SetValue(GetEmails.__ContextProperty, value);
    }
}

public static DependencyProperty __ListIdProperty = System.Workflow.ComponentModel.DependencyProperty.Register("__ListId", typeof(string), typeof(GetEmails));

[ValidationOption(ValidationOption.Required)]
public string __ListId
{
    get
    {
        return ((string)(base.GetValue(GetEmails.__ListIdProperty)));
    }
    set
    {
        base.SetValue(GetEmails.__ListIdProperty, value);
    }
}

public static DependencyProperty __ListItemProperty = System.Workflow.ComponentModel.DependencyProperty.Register("__ListItem", typeof(int), typeof(GetEmails));

[ValidationOption(ValidationOption.Required)]
public int __ListItem
{
    get
    {
        return ((int)(base.GetValue(GetEmails.__ListItemProperty)));
    }
    set
    {
        base.SetValue(GetEmails.__ListItemProperty, value);
    }
}

public static DependencyProperty __ActivationPropertiesProperty = DependencyProperty.Register("__ActivationProperties", typeof(Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties), typeof(GetEmails));

[ValidationOption(ValidationOption.Required)]
public Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties __ActivationProperties
{
    get
    {
        return (Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties)base.GetValue(GetEmails.__ActivationPropertiesProperty);
    }
    set
    {
        base.SetValue(GetEmails.__ActivationPropertiesProperty, value);
    }
}

第 2 步:然后在您的 .actions 文件中将这些属性的映射添加到您的块中(注意 __ListID、__ListItem、__Context 和 __ActivationProperties 的条目):

<Action Name="[DESCRIPTION OF YOUR ACTION]"
  ClassName="[Your.Namespace.Goes.Here].GetEmails"
  Assembly="[yourDLLName], Version=1.0.0.0, Culture=neutral, PublicKeyToken=0bfc6fa4c4aa913b"
  AppliesTo="all"
  Category="[Your Category Goes Here]">
  <RuleDesigner Sentence="[blah blah blah]">
    <FieldBind Field="PeopleFieldName" Text="people field" Id="1"/>
    <FieldBind Field="Output" Text="emailAddress" Id="2" DesignerType="parameterNames" />
  </RuleDesigner>
  <Parameters>
    <Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext" Direction="In" />
    <Parameter Name="__ListId" Type="System.String, mscorlib" Direction="In" />
    <Parameter Name="__ListItem" Type="System.Int32, mscorlib" Direction="In" />
    <Parameter Name="PeopleFieldName" Type="System.String, mscorlib" Direction="In" />
    <Parameter Name="Output" Type="System.String, mscorlib" Direction="Out" />
    <Parameter Name="__ActivationProperties" Type="Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties, Microsoft.SharePoint" Direction="Out" />
  </Parameters>
</Action>

第 3 步: 这是一个示例执行函数:

protected override ActivityExecutionStatus Execute(ActivityExecutionContext provider)
{
    Output = string.Empty;

    try
    {
        SPWeb web = __Context.Web;
        // get all of the information we currently have about the item
        // that this workflow is running on
        Guid listGuid = new Guid(__ListId);
        SPList myList = web.Lists[listGuid];
        SPListItem myItem = myList.GetItemById(__ListItem);

        //...
    }
    catch (Exception e)
    {
        //...
    }

    return ActivityExecutionStatus.Closed;
}

【讨论】:

  • 谢谢,这个解决方案帮助了我。
  • 优秀而彻底的答案。谢谢!
  • 谢谢!我们什么时候需要 ActivationProperties?
  • 我添加了 System.WindowsBase 以使其识别“DependencyProperty”和 System.Workflow,但由于缺少“Using”语句,我仍然到处都有大量错误:/
【解决方案2】:

我不确定这是否是 2010 API 的更改,但 __Context 属性提供了所有必要的部分,包括列表和项目。下面的示例包括@davek 的关于丢弃安全上下文的建议:

            var contextWeb = __Context.Web;
            var site = new SPSite(contextWeb.Url);
            var web = site.OpenWeb();

            var list = web.Lists[new Guid(__Context.ListId)];
            var item = list.GetItemById( __Context.ItemId);

【讨论】:

    【解决方案3】:

    Kit Menke 的回答非常全面,几乎涵盖了您需要的所有内容:我只会添加以下内容...

    如果你这样做:

    SPWeb tmpweb = __Context.Web;
    SPSite site = new SPSite(tmpweb.Url);
    SPWeb web = site.OpenWeb();
    

    而不是这个:

    SPWeb web = __Context.Web;
    ...
    

    那么您就摆脱了触发它的人传递给工作流的安全上下文。

    【讨论】:

      【解决方案4】:

      看看SPWorkflowActivationProperties.Item Property

      获取运行工作流实例的列表项。

      【讨论】:

      • 嗯.. 我从 SequenceActivity 基类实现我自己的活动。在这种情况下,我在哪里可以找到 SPWorkflowActivationProperties 实例?
      【解决方案5】:

      我尝试使用此代码并运行,但 contex 对象始终为空。有人知道为什么吗?

      protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
          {
      
      
              //return base.Execute(executionContext);
              int IdRetorno = -1;
      
      
      
              try {
                  SPSecurity.RunWithElevatedPrivileges(delegate
                  {
                      LogExceptionToWorkflowHistory("Inicio:", executionContext, WorkflowInstanceId);
                      using (SPSite sitio = new SPSite(this.__Context.Site.ID))
                      {
      
                          using (SPWeb web = sitio.AllWebs[this.__Context.Site.ID])
                          {
      
      
                              SPList sourceList = web.Lists[new Guid(ListId)];
                              LogExceptionToWorkflowHistory(ListId, executionContext, WorkflowInstanceId);
                              SPList destinoList = web.Lists[new Guid(SourceListId)];
                              LogExceptionToWorkflowHistory(SourceListId, executionContext, WorkflowInstanceId);
                              SPListItem sourceItem = sourceList.Items.GetItemById(ListItem);
                              LogExceptionToWorkflowHistory(ListItem.ToString(), executionContext, WorkflowInstanceId);
      
                              SPListItem destinoItem = destinoList.Items.Add();
                              CopyFieldValues(sourceItem, destinoItem);
                              destinoItem.SystemUpdate();
      
                              sourceItem.Delete();
                              IdRetorno = destinoItem.ID;
                          }
                      }
      
                  });
      
              }
              catch (Exception ex) {
                  if (!System.Diagnostics.EventLog.SourceExists("MyApp1"))
                      System.Diagnostics.EventLog.CreateEventSource(
                         "MyApp1", "Application");
      
                  EventLog EventLog1 = new EventLog();
                  EventLog1.Source = "MyApp1";
                  EventLog1.WriteEntry(ex.Message,EventLogEntryType.FailureAudit);
      
                  LogExceptionToWorkflowHistory(ex.Message, executionContext, WorkflowInstanceId);
              }
      
      
              OutListItemID = IdRetorno;
      
      
      
      
              return base.Execute(executionContext);
      
          }
      

      谢谢

      【讨论】:

      • 我的猜测是因为它被包装在 RunWithElevatedPrivileges 块中。我认为您必须以其他方式传递站点 ID?
      【解决方案6】:

      我不知道这是否太容易了,但我用过:

      objCurrentItem = workflowProperties.Item
      

      获取工作流中的项目(列表),然后更改列表中的项目

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多