使用 CSOM 创建 Project Server 2016 工作流
Posted
技术标签:
【中文标题】使用 CSOM 创建 Project Server 2016 工作流【英文标题】:Creating Project Server 2016 Workflow with CSOM 【发布时间】:2017-10-25 20:44:58 【问题描述】:查看信息:
https://dev.office.com/sharepoint/docs/general-development/working-with-the-sharepoint-workflow-services-client-side-object-model
和
https://sharepoint.stackexchange.com/questions/159432/programmatically-create-workflow-with-javascript-jsom-and-sp-workflowservices-w
我正在尝试为 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:活动 从范围命名为“WorkflowXaml_a2a3ddfc_8e29_488c_a7fa_110ad2e869fd” '/SharePoint/default/ec283308-a234-4501-9df1-99744cf4a5fe/b0993915-25fa-43f6-9839-8aa683f16ef2' 没有找到。从服务器接收到的 HTTP 标头 - ActivityId: e4085f69-addc-4c3e-8bcc-49c2f04daf7c。节点 ID:服务器。范围: /SharePoint/default/ec283308-a234-4501-9df1-99744cf4a5fe/b0993915-25fa-43f6-9839-8aa683f16ef2。 客户端 ActivityId : fa0ef59d-8566-1053-095'
这里没有任何线索。
【问题讨论】:
【参考方案1】:我通过使用 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();
【讨论】:
以上是关于使用 CSOM 创建 Project Server 2016 工作流的主要内容,如果未能解决你的问题,请参考以下文章
csharp 使用CSOM创建Sharepoint Wiki页面
使用 CSOM 进行初始部署后,将 SharePoint 列表 Web 部件添加到特定页面
使用 CSOM 404 未找到错误通过 Windows 服务将文件上传到 SharePoint 2010