如何在工作流活动(SharePoint)中获取上下文项

时间:2009-08-07 09:08:54

标签: sharepoint

我正在为sharepoint工作流编写自定义活动,我不知道如何使用当前的工作流程项,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例程对我来说太糟糕了。

也许还有另一个仅代码解决方案来获取Workflow活动中的上下文项?

6 个答案:

答案 0 :(得分:19)

答案是几个步骤:

  1. 将属性添加到自定义活动.cs
  2. 链接.actions文件中的属性(以便SPD知道如何映射到您的属性)
  3. 使用代码中的属性
  4. 第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;
    }
    

答案 1 :(得分:3)

我不确定这是否是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);

答案 2 :(得分:2)

Kit Menke的答案非常全面,涵盖了您所需要的一切:我只会添加以下内容......

如果你这样做:

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

而不是:

SPWeb web = __Context.Web;
...

然后你就可以解除被触发它的人传递给工作流的安全上下文。

答案 3 :(得分:1)

查看SPWorkflowActivationProperties.Item Property

  

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

答案 4 :(得分:1)

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

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);

    }

感谢

答案 5 :(得分:1)

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

objCurrentItem = workflowProperties.Item

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