【问题标题】:Sitecore: Assign workflow to an item programmaticallySitecore:以编程方式将工作流分配给项目
【发布时间】:2012-11-23 11:43:06
【问题描述】:

我已经配置了一个工作流程,像往常一样以“草稿”状态开始。我已经为模板的标准值配置了工作流程。它在内容编辑器中完美运行。 (当我使用内容编辑器创建项目时,一旦创建项目,工作流就会分配给项目,并且它的状态变为“草稿”。)

但是当我在上述模板下以编程方式创建项目时,它不会分配工作流。 我应该怎么做才能分配工作流?如果有,请分享任何代码示例。

谢谢。

Sitecore.Data.Items.TemplateItem template = this.MasterDatabase.GetItem("/sitecore/templates/user defined/sample types");
Sitecore.Data.Items.Item parent = this.MasterDatabase.GetItem(parentId); 

Sitecore.Data.Items.Item newItem;                
// Create new item and retrieve it
newItem = template.CreateItemFrom("sampleName", parent);

newItem.Editing.BeginEdit();

newItem.Name = StringFormatter.CreateItemNameFromID(this.newItem);
newItem.Fields["Title"].Value = "Sample Title"

newItem.Editing.EndEdit();

【问题讨论】:

    标签: c# sitecore sitecore-workflow


    【解决方案1】:

    我不会使用 Dhanuka777 的答案,因为它没有利用 Sitecore 的工作流状态命令和它附带的有用功能,例如电子邮件生成。它还需要硬编码 Guid。

    以下代码的好处:

    • 利用 Sitecore 的状态命令及其出色的功能 有例如生成电子邮件以提醒用户等
    • 不要将状态和命令的 Guid 存储在解决方案中
    • 独立于 Sitecore 的上下文
    • 摘要,因此可用于 Sitecore 中的所有工作流。
        public bool UpdateWorkflow(WorkflowState newWorkflowState, Item item)
        {
            Assert.ArgumentNotNull(newWorkflowState, "The new WorkflowState can not be null");
            Assert.ArgumentNotNull(item, "Item can not be null");
    
            bool successful = false;
    
            WorkflowState currentWorkflowState = GetWorkflowStateForItem(item);
    
            if (currentWorkflowState != newWorkflowState)
            {
                IWorkflow workflow = GetWorkflowOfItem(item);
    
                if (workflow != null)
                {
                    List<WorkflowCommand> applicableWorkflowCommands = workflow.GetCommands(currentWorkflowState.StateID).ToList();
    
                    foreach (var applicableWorkflowCommand in applicableWorkflowCommands)
                    {
                        Item commandItem = _database.GetItem(applicableWorkflowCommand.CommandID);
    
                        string nextStateId = commandItem["Next state"];
    
                        if (nextStateId == newWorkflowState.StateID)
                        {
                            WorkflowResult workflowResult = workflow.Execute(applicableWorkflowCommand.CommandID, item, "", false);
                            successful = workflowResult.Succeeded;
                            break;
                        }
                    }
                }
            }
            else
            {
                successful = true;
            }
    
            return successful;
        }
    
        public WorkflowState GetWorkflowStateForItem(Item item)
        {
            var workflow = GetWorkflowOfItem(item);
            return workflow != null ? workflow.GetState(item) : null;
        }
    
        public IWorkflow GetWorkflowOfItem(Item item)
        {
            return _database.WorkflowProvider.GetWorkflow(item);
        }
    
        private Database _database
        {
            get
            {
                return Sitecore.Data.Database.GetDatabase("master");
            }
        }
    

    【讨论】:

    • 我不认为这个带有 4(!) 嵌套 if 语句的过于复杂的代码应该是做某事的“正确”方式。此外,似乎没有回答这个问题:如何将工作流和随机工作流状态分配给项目。相反,如果下一个状态恰好是所需状态,它基本上会将项目移动到下一个工作流状态。
    【解决方案2】:

    解决了标准字段的问题,

    newItem.Editing.BeginEdit();                    
    newItem.Fields["__Workflow"].Value = "{4D1F00EF-CA5D-4F36-A51E-E77E2BAE4A24}"; //Set workflow
    newItem.Fields["__Workflow state"].Value = "{7F39DF46-B4B9-4D08-A0D4-32DE6FD643D1}"; //Set   workflow state to Unposted.
    newClassified.Editing.EndEdit();  
    

    【讨论】:

    • 我到处查看,这似乎是最好的答案,我想知道为什么它不会自动发生。
    • 不要使用这种方式来设置硬编码的Guids。使用 jRobbins 答案正确设置。
    • 对于我们的特殊需要,硬编码的 ID 对我们来说很好。需要注意的一点是,您可以使用Sitecore.FieldIDs.WorkflowSitecore.FieldIDs.WorkflowState 而不是__Workflow[...]。例如:itemVersion.Fields[Sitecore.FieldIDs.WorkflowState].Value = approvedState.ToString();.
    • 关于“硬编码 ID”,实际上我们必须在任何 Sitecore 项目中使用硬编码 ID(例如代码值、工作流状态(检查它是否处于特定状态)等) ,最佳做法是为这些硬编码的项目 ID 设置一组单独的静态类。
    【解决方案3】:

    我到处寻找一个好的答案。我正在创建一个新项目并想开始它的工作流程。 jRobbins 的回答对我不起作用,因为如果项目的当前工作流状态为 null 并且它没有提供设置初始工作流状态的好方法,它会引发异常。

    以下内容对我有用:

    var workflow = Factory.GetDatabase("master").WorkflowProvider.GetWorkflow(workflowId);
    workflow.Start(item);
    

    这会设置我的新项目的工作流程,并将其工作流程状态设置为初始状态。

    【讨论】:

      【解决方案4】:

      在确保我在标准值上设置了默认工作流程之后,以下组合,感谢上面的海报,完美地工作:

      var workflowId = item.Fields["__Default workflow"].Value;
      var workflow = Factory.GetDatabase("master").WorkflowProvider.GetWorkflow(workflowId);
      workflow.Start(item);
      

      【讨论】:

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