使用 CSOM 创建 Project Server 2016 工作流
Creating Project Server 2016 Workflow with CSOM
正在查看信息:
和
我正在尝试为 Project Server 2016 创建网站工作流 - 这意味着它的平台类型必须是 SharePoint 2013 Workflow - Project Server
就像关于 stackexchange 的问题一样,首先我从 spd 2013 创建了示例工作流,保存为模板并将生成的 xaml 检索到我的 xaml 字符串。
ProjectContext psContext = new ProjectContext(Strings.PWA_Url);
var web = psContext.Web;
var siteCollection = psContext.Site;
var tasksList = web.Lists.GetByTitle("Project Server Workflow Tasks");
var historyList = web.Lists.GetByTitle("Project Server Workflow History");
string xaml = "<Activity mc:Ignorable="mwaw" x:Class="Test.MTW" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:local="clr-namespace:Microsoft.Office.Project.Server.WorkflowActivities" xmlns:local1="clr-namespace:Microsoft.SharePoint.WorkflowServices.Activities" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mwaw="clr-namespace:Microsoft.Web.Authoring.Workflow;assembly=Microsoft.Web.Authoring" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><Sequence><Sequence><mwaw:SPDesignerXamlWriter.CustomAttributes><scg:Dictionary x:TypeArguments="x:String, x:String"><x:String x:Key="InitBlock">InitBlock-7751C281-B0D1-4336-87B4-83F2198EDE6D</x:String></scg:Dictionary></mwaw:SPDesignerXamlWriter.CustomAttributes></Sequence><Flowchart StartNode="{x:Reference __ReferenceID1}"><FlowStep x:Name="__ReferenceID1"><mwaw:SPDesignerXamlWriter.CustomAttributes><scg:Dictionary x:TypeArguments="x:String, x:String" /></mwaw:SPDesignerXamlWriter.CustomAttributes><Sequence><mwaw:SPDesignerXamlWriter.CustomAttributes><scg:Dictionary x:TypeArguments="x:String, x:String"><x:String x:Key="StageAttribute">StageContainer-8EDBFE6D-DA0D-42F6-A806-F5807380DA4D</x:String></scg:Dictionary></mwaw:SPDesignerXamlWriter.CustomAttributes><local:EnterProjectStage StageId="296334d9-1621-e711-80c8-00155d014d18"><mwaw:SPDesignerXamlWriter.CustomAttributes><scg:Dictionary x:TypeArguments="x:String, x:String"><x:String x:Key="StageAttribute">StageHeader-7FE15537-DFDB-4198-ABFA-8AF8B9D669AE</x:String></scg:Dictionary></mwaw:SPDesignerXamlWriter.CustomAttributes></local:EnterProjectStage><Sequence DisplayName="Inicjalizacja"><local1:SetWorkflowStatus Disabled="False" Status="Entering stage: Inicjalizacja" /></Sequence><local:ExitProjectStageGate><mwaw:SPDesignerXamlWriter.CustomAttributes><scg:Dictionary x:TypeArguments="x:String, x:String"><x:String x:Key="StageAttribute">StageFooter-3A59FA7C-C493-47A1-8F8B-1F481143EB08</x:String></scg:Dictionary></mwaw:SPDesignerXamlWriter.CustomAttributes></local:ExitProjectStageGate></Sequence><FlowStep.Next><FlowStep x:Name="__ReferenceID0"><mwaw:SPDesignerXamlWriter.CustomAttributes><scg:Dictionary x:TypeArguments="x:String, x:String"><x:String x:Key="Next">4294967294</x:String></scg:Dictionary></mwaw:SPDesignerXamlWriter.CustomAttributes><Sequence><mwaw:SPDesignerXamlWriter.CustomAttributes><scg:Dictionary x:TypeArguments="x:String, x:String"><x:String x:Key="StageAttribute">StageContainer-8EDBFE6D-DA0D-42F6-A806-F5807380DA4D</x:String></scg:Dictionary></mwaw:SPDesignerXamlWriter.CustomAttributes><local:EnterProjectStage StageId="e10db6c9-1721-e711-80c8-00155d014d18"><mwaw:SPDesignerXamlWriter.CustomAttributes><scg:Dictionary x:TypeArguments="x:String, x:String"><x:String x:Key="StageAttribute">StageHeader-7FE15537-DFDB-4198-ABFA-8AF8B9D669AE</x:String></scg:Dictionary></mwaw:SPDesignerXamlWriter.CustomAttributes></local:EnterProjectStage><Sequence DisplayName="Akceptacja"><local1:SetWorkflowStatus Disabled="False" Status="Entering stage: Akceptacja" /></Sequence><local:ExitProjectStageGate><mwaw:SPDesignerXamlWriter.CustomAttributes><scg:Dictionary x:TypeArguments="x:String, x:String"><x:String x:Key="StageAttribute">StageFooter-3A59FA7C-C493-47A1-8F8B-1F481143EB08</x:String></scg:Dictionary></mwaw:SPDesignerXamlWriter.CustomAttributes></local:ExitProjectStageGate></Sequence></FlowStep></FlowStep.Next></FlowStep><x:Reference>__ReferenceID0</x:Reference></Flowchart></Sequence></Activity>"
psContext.Load(web);
psContext.Load(siteCollection);
psContext.Load(tasksList);
psContext.Load(historyList);
psContext.ExecuteQuery();
WorkflowServicesManager wfServiceManager = new WorkflowServicesManager(psContext, web);
WorkflowDeploymentService deployService = wfServiceManager.GetWorkflowDeploymentService();
WorkflowSubscriptionService subscriptionService = wfServiceManager.GetWorkflowSubscriptionService();
WorkflowDefinition wfDefinition = new WorkflowDefinition(psContext);
wfDefinition.DisplayName = "TestWorkflow";
wfDefinition.Description = "TestWorkflow";
wfDefinition.Xaml = xaml;
wfDefinition.RestrictToType = "Site";
deployService.SaveDefinition(wfDefinition);
psContext.Load(wfDefinition, i => i.Id);
psContext.ExecuteQuery();
Guid subscriptionID = Guid.NewGuid();
WorkflowSubscription subscription = new WorkflowSubscription(psContext);
subscription.Id = subscriptionID;
subscription.Name = "TestWorkflow";
subscription.DefinitionId = wfDefinition.Id;
subscription.EventSourceId = web.Id;
subscription.EventTypes = new List<string>() { "WorkflowStart" };
subscription.SetProperty("HistoryListId", historyList.Id.ToString("B"));
subscription.SetProperty("TaskListId", tasksList.Id.ToString("B"));
subscriptionService.PublishSubscription(subscription);
psContext.ExecuteQuery();
但这让我在最后一行代码中出错:
Microsoft.SharePoint.Client.ServerException:
'Microsoft.Workflow.Client.ActivityNotFoundException: The activity
named 'WorkflowXaml_a2a3ddfc_8e29_488c_a7fa_110ad2e869fd' from scope
'/SharePoint/default/ec283308-a234-4501-9df1-99744cf4a5fe/b0993915-25fa-43f6-9839-8aa683f16ef2'
was not found. HTTP headers received from the server - ActivityId:
e4085f69-addc-4c3e-8bcc-49c2f04daf7c. NodeId: SERVER. Scope:
/SharePoint/default/ec283308-a234-4501-9df1-99744cf4a5fe/b0993915-25fa-43f6-9839-8aa683f16ef2.
Client ActivityId : fa0ef59d-8566-1053-095'
这里没有任何线索。
我通过使用 Fiddler 嗅探 SharePoint Designer 2013 CSOM 通信来实现它。
实现此功能的关键是:
wfDefinition.SetProperty("IsProjectMode", "true");
// (...)
subscription.EventSourceId = new Guid("5122D555-E672-4E5D-A7C4-8084E694A257");
subscription.SetProperty("Microsoft.ProjectServer.ActivationProperties.CurrentStageId", "");
subscription.SetProperty("Microsoft.SharePoint.ActivationProperties.ParentContentTypeId", "");
subscription.SetProperty("Microsoft.ProjectServer.ActivationProperties.ProjectId", "");
subscription.SetProperty("Microsoft.ProjectServer.ActivationProperties.RequestedStageId", "");
注释的属性都是由 SPD 设置的,但不是必需的。
工作代码:
ProjectContext psContext = new ProjectContext(Strings.PWA_Url);
var web = psContext.Web;
var siteCollection = psContext.Site;
var tasksList = web.Lists.GetByTitle("Project Server Workflow Tasks");
var historyList = web.Lists.GetByTitle("Project Server Workflow History");
psContext.Load(web, i => i.Id);
psContext.Load(siteCollection, i => i.Id);
psContext.Load(tasksList, i => i.Id);
psContext.Load(historyList, i => i.Id);
psContext.ExecuteQuery();
WorkflowServicesManager wfServiceManager = new WorkflowServicesManager(psContext, web);
WorkflowDefinition wfDefinition = new WorkflowDefinition(psContext);
Guid subscriptionID = Guid.NewGuid();
wfDefinition.DisplayName = "TestWorkflow";
wfDefinition.Description = "TestWorkflow";
wfDefinition.Xaml = Strings.Workflow_Simple;
wfDefinition.SetProperty("isReusable", "false");
wfDefinition.SetProperty("IsProjectMode", "true");
//wfDefinition.SetProperty("AutosetStatusToStageName", "false");
//wfDefinition.SetProperty("SPDConfig.LastEditMode", "TextBased");
wfDefinition.SetProperty("RestrictToType", "Site");
wfDefinition.SetProperty("TaskListId", tasksList.Id.ToString("B"));
wfDefinition.SetProperty("HistoryListId", historyList.Id.ToString("B"));
//wfDefinition.SetProperty("SPDConfig.StartManually", "true");
//wfDefinition.SetProperty("SPDConfig.StartOnCreate", "false");
//wfDefinition.SetProperty("SPDConfig.StartOnChange", "false");
//wfDefinition.SetProperty("FormField", "<Fields />");
//wfDefinition.SetProperty("RequiresInitiationForm", "false");
//wfDefinition.SetProperty("InitiationUrl", "");
//wfDefinition.SetProperty("SubscriptionId", subscriptionID.ToString("B"));
//wfDefinition.SetProperty("SubscriptionName", "TestWorkflow");
WorkflowDeploymentService deployService = wfServiceManager.GetWorkflowDeploymentService();
deployService.SaveDefinition(wfDefinition);
psContext.Load(wfDefinition, i => i.Id);
psContext.ExecuteQuery();
deployService.PublishDefinition(wfDefinition.Id);
psContext.ExecuteQuery();
WorkflowSubscription subscription = new WorkflowSubscription(psContext);
subscription.Id = subscriptionID;
subscription.Name = "TestWorkflow";
subscription.EventSourceId = new Guid("5122D555-E672-4E5D-A7C4-8084E694A257");
subscription.EventTypes = new List<string>() { "WorkflowStart" };
subscription.DefinitionId = wfDefinition.Id;
//subscription.SetProperty("CreatedBySPD", "1");
subscription.SetProperty("CurrentWebUri", Strings.PWA_Url_Https);
subscription.SetProperty("HistoryListId", historyList.Id.ToString("B"));
subscription.SetProperty("Microsoft.ProjectServer.ActivationProperties.CurrentStageId", "");
//subscription.SetProperty("SharePointWorkflowContext.ActivationProperties.SiteId", siteCollection.Id.ToString("B"));
subscription.SetProperty("TaskListId", tasksList.Id.ToString("B"));
subscription.SetProperty("Microsoft.SharePoint.ActivationProperties.ParentContentTypeId", "");
//subscription.SetProperty("SharePointWorkflowContext.ActivationProperties.WebId", web.Id.ToString("B"));
subscription.SetProperty("Microsoft.ProjectServer.ActivationProperties.ProjectId", "");
subscription.SetProperty("Microsoft.ProjectServer.ActivationProperties.RequestedStageId", "");
WorkflowSubscriptionService subscriptionService = wfServiceManager.GetWorkflowSubscriptionService();
subscriptionService.PublishSubscription(subscription);
psContext.ExecuteQuery();
正在查看信息:
和
我正在尝试为 Project Server 2016 创建网站工作流 - 这意味着它的平台类型必须是 SharePoint 2013 Workflow - Project Server
就像关于 stackexchange 的问题一样,首先我从 spd 2013 创建了示例工作流,保存为模板并将生成的 xaml 检索到我的 xaml 字符串。
ProjectContext psContext = new ProjectContext(Strings.PWA_Url);
var web = psContext.Web;
var siteCollection = psContext.Site;
var tasksList = web.Lists.GetByTitle("Project Server Workflow Tasks");
var historyList = web.Lists.GetByTitle("Project Server Workflow History");
string xaml = "<Activity mc:Ignorable="mwaw" x:Class="Test.MTW" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:local="clr-namespace:Microsoft.Office.Project.Server.WorkflowActivities" xmlns:local1="clr-namespace:Microsoft.SharePoint.WorkflowServices.Activities" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mwaw="clr-namespace:Microsoft.Web.Authoring.Workflow;assembly=Microsoft.Web.Authoring" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"><Sequence><Sequence><mwaw:SPDesignerXamlWriter.CustomAttributes><scg:Dictionary x:TypeArguments="x:String, x:String"><x:String x:Key="InitBlock">InitBlock-7751C281-B0D1-4336-87B4-83F2198EDE6D</x:String></scg:Dictionary></mwaw:SPDesignerXamlWriter.CustomAttributes></Sequence><Flowchart StartNode="{x:Reference __ReferenceID1}"><FlowStep x:Name="__ReferenceID1"><mwaw:SPDesignerXamlWriter.CustomAttributes><scg:Dictionary x:TypeArguments="x:String, x:String" /></mwaw:SPDesignerXamlWriter.CustomAttributes><Sequence><mwaw:SPDesignerXamlWriter.CustomAttributes><scg:Dictionary x:TypeArguments="x:String, x:String"><x:String x:Key="StageAttribute">StageContainer-8EDBFE6D-DA0D-42F6-A806-F5807380DA4D</x:String></scg:Dictionary></mwaw:SPDesignerXamlWriter.CustomAttributes><local:EnterProjectStage StageId="296334d9-1621-e711-80c8-00155d014d18"><mwaw:SPDesignerXamlWriter.CustomAttributes><scg:Dictionary x:TypeArguments="x:String, x:String"><x:String x:Key="StageAttribute">StageHeader-7FE15537-DFDB-4198-ABFA-8AF8B9D669AE</x:String></scg:Dictionary></mwaw:SPDesignerXamlWriter.CustomAttributes></local:EnterProjectStage><Sequence DisplayName="Inicjalizacja"><local1:SetWorkflowStatus Disabled="False" Status="Entering stage: Inicjalizacja" /></Sequence><local:ExitProjectStageGate><mwaw:SPDesignerXamlWriter.CustomAttributes><scg:Dictionary x:TypeArguments="x:String, x:String"><x:String x:Key="StageAttribute">StageFooter-3A59FA7C-C493-47A1-8F8B-1F481143EB08</x:String></scg:Dictionary></mwaw:SPDesignerXamlWriter.CustomAttributes></local:ExitProjectStageGate></Sequence><FlowStep.Next><FlowStep x:Name="__ReferenceID0"><mwaw:SPDesignerXamlWriter.CustomAttributes><scg:Dictionary x:TypeArguments="x:String, x:String"><x:String x:Key="Next">4294967294</x:String></scg:Dictionary></mwaw:SPDesignerXamlWriter.CustomAttributes><Sequence><mwaw:SPDesignerXamlWriter.CustomAttributes><scg:Dictionary x:TypeArguments="x:String, x:String"><x:String x:Key="StageAttribute">StageContainer-8EDBFE6D-DA0D-42F6-A806-F5807380DA4D</x:String></scg:Dictionary></mwaw:SPDesignerXamlWriter.CustomAttributes><local:EnterProjectStage StageId="e10db6c9-1721-e711-80c8-00155d014d18"><mwaw:SPDesignerXamlWriter.CustomAttributes><scg:Dictionary x:TypeArguments="x:String, x:String"><x:String x:Key="StageAttribute">StageHeader-7FE15537-DFDB-4198-ABFA-8AF8B9D669AE</x:String></scg:Dictionary></mwaw:SPDesignerXamlWriter.CustomAttributes></local:EnterProjectStage><Sequence DisplayName="Akceptacja"><local1:SetWorkflowStatus Disabled="False" Status="Entering stage: Akceptacja" /></Sequence><local:ExitProjectStageGate><mwaw:SPDesignerXamlWriter.CustomAttributes><scg:Dictionary x:TypeArguments="x:String, x:String"><x:String x:Key="StageAttribute">StageFooter-3A59FA7C-C493-47A1-8F8B-1F481143EB08</x:String></scg:Dictionary></mwaw:SPDesignerXamlWriter.CustomAttributes></local:ExitProjectStageGate></Sequence></FlowStep></FlowStep.Next></FlowStep><x:Reference>__ReferenceID0</x:Reference></Flowchart></Sequence></Activity>"
psContext.Load(web);
psContext.Load(siteCollection);
psContext.Load(tasksList);
psContext.Load(historyList);
psContext.ExecuteQuery();
WorkflowServicesManager wfServiceManager = new WorkflowServicesManager(psContext, web);
WorkflowDeploymentService deployService = wfServiceManager.GetWorkflowDeploymentService();
WorkflowSubscriptionService subscriptionService = wfServiceManager.GetWorkflowSubscriptionService();
WorkflowDefinition wfDefinition = new WorkflowDefinition(psContext);
wfDefinition.DisplayName = "TestWorkflow";
wfDefinition.Description = "TestWorkflow";
wfDefinition.Xaml = xaml;
wfDefinition.RestrictToType = "Site";
deployService.SaveDefinition(wfDefinition);
psContext.Load(wfDefinition, i => i.Id);
psContext.ExecuteQuery();
Guid subscriptionID = Guid.NewGuid();
WorkflowSubscription subscription = new WorkflowSubscription(psContext);
subscription.Id = subscriptionID;
subscription.Name = "TestWorkflow";
subscription.DefinitionId = wfDefinition.Id;
subscription.EventSourceId = web.Id;
subscription.EventTypes = new List<string>() { "WorkflowStart" };
subscription.SetProperty("HistoryListId", historyList.Id.ToString("B"));
subscription.SetProperty("TaskListId", tasksList.Id.ToString("B"));
subscriptionService.PublishSubscription(subscription);
psContext.ExecuteQuery();
但这让我在最后一行代码中出错:
Microsoft.SharePoint.Client.ServerException: 'Microsoft.Workflow.Client.ActivityNotFoundException: The activity named 'WorkflowXaml_a2a3ddfc_8e29_488c_a7fa_110ad2e869fd' from scope '/SharePoint/default/ec283308-a234-4501-9df1-99744cf4a5fe/b0993915-25fa-43f6-9839-8aa683f16ef2' was not found. HTTP headers received from the server - ActivityId: e4085f69-addc-4c3e-8bcc-49c2f04daf7c. NodeId: SERVER. Scope: /SharePoint/default/ec283308-a234-4501-9df1-99744cf4a5fe/b0993915-25fa-43f6-9839-8aa683f16ef2. Client ActivityId : fa0ef59d-8566-1053-095'
这里没有任何线索。
我通过使用 Fiddler 嗅探 SharePoint Designer 2013 CSOM 通信来实现它。
实现此功能的关键是:
wfDefinition.SetProperty("IsProjectMode", "true");
// (...)
subscription.EventSourceId = new Guid("5122D555-E672-4E5D-A7C4-8084E694A257");
subscription.SetProperty("Microsoft.ProjectServer.ActivationProperties.CurrentStageId", "");
subscription.SetProperty("Microsoft.SharePoint.ActivationProperties.ParentContentTypeId", "");
subscription.SetProperty("Microsoft.ProjectServer.ActivationProperties.ProjectId", "");
subscription.SetProperty("Microsoft.ProjectServer.ActivationProperties.RequestedStageId", "");
注释的属性都是由 SPD 设置的,但不是必需的。
工作代码:
ProjectContext psContext = new ProjectContext(Strings.PWA_Url);
var web = psContext.Web;
var siteCollection = psContext.Site;
var tasksList = web.Lists.GetByTitle("Project Server Workflow Tasks");
var historyList = web.Lists.GetByTitle("Project Server Workflow History");
psContext.Load(web, i => i.Id);
psContext.Load(siteCollection, i => i.Id);
psContext.Load(tasksList, i => i.Id);
psContext.Load(historyList, i => i.Id);
psContext.ExecuteQuery();
WorkflowServicesManager wfServiceManager = new WorkflowServicesManager(psContext, web);
WorkflowDefinition wfDefinition = new WorkflowDefinition(psContext);
Guid subscriptionID = Guid.NewGuid();
wfDefinition.DisplayName = "TestWorkflow";
wfDefinition.Description = "TestWorkflow";
wfDefinition.Xaml = Strings.Workflow_Simple;
wfDefinition.SetProperty("isReusable", "false");
wfDefinition.SetProperty("IsProjectMode", "true");
//wfDefinition.SetProperty("AutosetStatusToStageName", "false");
//wfDefinition.SetProperty("SPDConfig.LastEditMode", "TextBased");
wfDefinition.SetProperty("RestrictToType", "Site");
wfDefinition.SetProperty("TaskListId", tasksList.Id.ToString("B"));
wfDefinition.SetProperty("HistoryListId", historyList.Id.ToString("B"));
//wfDefinition.SetProperty("SPDConfig.StartManually", "true");
//wfDefinition.SetProperty("SPDConfig.StartOnCreate", "false");
//wfDefinition.SetProperty("SPDConfig.StartOnChange", "false");
//wfDefinition.SetProperty("FormField", "<Fields />");
//wfDefinition.SetProperty("RequiresInitiationForm", "false");
//wfDefinition.SetProperty("InitiationUrl", "");
//wfDefinition.SetProperty("SubscriptionId", subscriptionID.ToString("B"));
//wfDefinition.SetProperty("SubscriptionName", "TestWorkflow");
WorkflowDeploymentService deployService = wfServiceManager.GetWorkflowDeploymentService();
deployService.SaveDefinition(wfDefinition);
psContext.Load(wfDefinition, i => i.Id);
psContext.ExecuteQuery();
deployService.PublishDefinition(wfDefinition.Id);
psContext.ExecuteQuery();
WorkflowSubscription subscription = new WorkflowSubscription(psContext);
subscription.Id = subscriptionID;
subscription.Name = "TestWorkflow";
subscription.EventSourceId = new Guid("5122D555-E672-4E5D-A7C4-8084E694A257");
subscription.EventTypes = new List<string>() { "WorkflowStart" };
subscription.DefinitionId = wfDefinition.Id;
//subscription.SetProperty("CreatedBySPD", "1");
subscription.SetProperty("CurrentWebUri", Strings.PWA_Url_Https);
subscription.SetProperty("HistoryListId", historyList.Id.ToString("B"));
subscription.SetProperty("Microsoft.ProjectServer.ActivationProperties.CurrentStageId", "");
//subscription.SetProperty("SharePointWorkflowContext.ActivationProperties.SiteId", siteCollection.Id.ToString("B"));
subscription.SetProperty("TaskListId", tasksList.Id.ToString("B"));
subscription.SetProperty("Microsoft.SharePoint.ActivationProperties.ParentContentTypeId", "");
//subscription.SetProperty("SharePointWorkflowContext.ActivationProperties.WebId", web.Id.ToString("B"));
subscription.SetProperty("Microsoft.ProjectServer.ActivationProperties.ProjectId", "");
subscription.SetProperty("Microsoft.ProjectServer.ActivationProperties.RequestedStageId", "");
WorkflowSubscriptionService subscriptionService = wfServiceManager.GetWorkflowSubscriptionService();
subscriptionService.PublishSubscription(subscription);
psContext.ExecuteQuery();