SharePoint workflow to jedno z pojęć, które jest bardzo mocno związane z tą platformą i które jest jedną z tych opcji, dla której ją wdrażamy. To co dziś chciałbym Wam pokazać to możliwość uruchamiania workflow z poziomu zwykłej aplikacji konsolowej. I o ile w przypadku środowiska lokalnego nie jest to jakieś bardzo krytyczne, mamy w końcu możliwość tworzenia Timer Job, to już dla SharePoint online jest to bezcenne.
Mogę powiedzieć z swojego doświadczenia ostatnich dni, że opcja jest wręcz nieoceniona. Wyobraźmy sobie sytuację, że mamy napisany SharePoint workflow, który resetuje nam codziennie statusy na elementach listy. Niestety w chmurze nie mamy opcji aby zaplanować takie zadanie. Opcją, które dla sprawdza się rewelacyjnie jest napisanie aplikacji konsolowej, które startuje proces. Następnie aplikację publikuję sobie jako Azure WebJob, którą scheduler Azure uruchamia mi codziennie rano. Naprawdę proste i niezawodne.
[adblockingdetector id=”577b6d6010f9e”]
Konfigurowanie aplikacji do pracy z SharePoint online
Pierwszym krokiem jest wygenerowanie tokena, który pozwoli się na uwierzytelnić. O tym jak to zrobić pisałem już wcześniej tutaj, więc tutaj nie będę już się powtarzał. Kolejnym krokiem jest stworzenie zwykłej aplikacji konsolowej w Visual Studio i instalacja w NuGet Package Manager AppForSharePointWebToolkit. Konfigurujemy projekt zgodnie z tym co opisałem we wcześniejszym artykule, aby aplikacja miała dostęp do naszego tenantu w Office 365.
Metoda startująca SharePoint workflow
Pierwszym niezbędnym elementem, w naszym projekcie jest referencja do „Microsoft.SharePoint.Client.WorkflowServices”. Zawiera on niezbędne klasy do pracy z workflow.
Poniżej możecie zobaczyć metodę, która tak naprawdę robi całą pracę. Cała operacja składa się z trzech bloków. Najpierw znajdujemy instancję naszego workflow, potem budujemy sobie kolekcje elementów dla wybranej listy. Na koniec zaś dla każdego elementu naszej kolekcji uruchamiamy SharePoint Workflow. I to tyle
Z tego co ważne to warto zwrócić uwagę na to, że:
- spacje w CamlQuary trzeba zastąpić zapisem _x0020_ inaczej zapytanie nam nie zadziała
- Musimy podać nazwę workflow, który mamy w naszym site collection aby móc uruchomić właściwy proces
[code lang="csharp"] private static void RunReminder(ClientContext clientContext) { Web web = clientContext.Web; WorkflowServicesManager wfServicesManager = new WorkflowServicesManager(clientContext, web); WorkflowDeploymentService wfDeploymentService = wfServicesManager.GetWorkflowDeploymentService(); WorkflowDefinitionCollection wfDefinitionCollection = wfDeploymentService.EnumerateDefinitions(false); clientContext.Load(wfDefinitionCollection, wfDefs => wfDefs.Where(wfd => wfd.DisplayName == "Reminder")); clientContext.ExecuteQuery(); WorkflowDefinition wfDefinition = wfDefinitionCollection.First(); var workflowSubscriptionService = wfServicesManager.GetWorkflowSubscriptionService(); var workflowAssociations = workflowSubscriptionService.EnumerateSubscriptionsByDefinition(wfDefinition.Id); clientContext.Load(workflowAssociations); clientContext.ExecuteQuery(); var firstWorkflowAssociation = workflowAssociations.First(); var workflowInstanceService = wfServicesManager.GetWorkflowInstanceService(); var startParameters = new Dictionary<string, object>(); List employeesList = clientContext.Web.Lists.GetByTitle("Employees"); CamlQuery query = new CamlQuery(); query.ViewXml = "<View><Query><Where>" + "<And>" + "<Contains>" + "<FieldRef Name='Lunch_x0020_Ordered'/><Value Type='Boolean'>0</Value>" + "</Contains>" + "<Contains>" + "<FieldRef Name='Out_x0020_of_x0020_office'/><Value Type='Boolean'>0</Value>" + "</Contains>" + "</And>" + "</Where></Query></View>"; ListItemCollection collection = employeesList.GetItems(query); clientContext.Load(collection); try { clientContext.ExecuteQuery(); } catch (Exception exception) { Console.WriteLine("There were exception on Shoes list: " + exception.Message + "Application will be terminated!!!"); Environment.Exit(1); } foreach (var item in collection) { Console.WriteLine("starting first workflow on " + item.Id); workflowInstanceService.StartWorkflowOnListItem(firstWorkflowAssociation, item.Id, startParameters); clientContext.ExecuteQuery(); } clientContext.Dispose(); } } [/code]