Работа с облачными потоками с помощью кода

Все потоки хранятся в Dataverse и для управления ими можно использовать пакет SDK Dataverse для .NET или веб-API.

Эта статья описывает возможности управления потоками на вкладке Решения в Power Automate. В настоящее время управление потоками в разделе Мои потоки не поддерживается с помощью кода.

Взаимодействие с API-интерфейсами Dataverse

Dataverse предоставляет эквивалентные возможности с использованием пакета SDK Dataverse для .NET или веб-API.

Какой метод выбрать?

Лучший метод зависит от технологии проекта и ваших навыков.

Если в вашем проекте используется .NET, мы рекомендуем использовать пакет SDK. Пакет SDK упрощает процесс разработки, предоставляя типизированную объектную модель и методы для аутентификации.

Дополнительная информация: Использование службы организации

Как установить подключение?

Способ подключения зависит от того, используете ли вы пакет SDK Dataverse для .NET или веб-API.

При использовании пакета SDK вам необходимо подключиться к клиентскому приложению, чтобы получить доступ к экземпляру IOrganizationService. IOrganizationService — это интерфейс, предоставляющий методы, которые вы можете использовать для взаимодействия с Dataverse.

Подробнее:

Таблица рабочих процессов

Облачные потоки хранятся в таблице Процесс (рабочий процесс), которая представлена в веб-API как тип сущности EntityType рабочего процесса

В следующей таблице описаны важные столбцы в таблице рабочих процессов:

Логическое имя Type Описание:
category Выбранный вариант Категория потока. Вот разные категории.
0 — классические рабочие процессы Dataverse.
1 — классические диалоги Dataverse.
2 — бизнес-правила.
3 — классические действия Dataverse.
4 — потоки бизнес-процессов.
5 — современный поток ("Автоматизированный", "Мгновенный" или "По расписанию").
6 — классические потоки.
clientdata String Строковый JSON определения потока и его connectionReferences.
createdby Подстановка Пользователь, который создал поток.
createdon Дата/время Дата создания потока.
description String Предоставляемое пользователем описание потока.
ismanaged Bool Указывает, был ли поток установлен с помощью управляемого решения.
modifiedby Подстановка Последний пользователь, который обновил поток.
modifiedon Дата/время Время последнего обновления потока.
name String Отображаемое имя, которое вы дали потоку.
ownerid Подстановка Пользователь или рабочая группа, ответственные за поток.
statecode Выбранный вариант Состояние потока. Статусом может быть следующий:
0 — черновик (выкл.)
1 — активировано (вкл.)
2 — приостановлено.
type Выбранный вариант Указывает, является ли поток работающим потоком или шаблоном, который можно использовать для создания других потоков.
1 — определение
2 — активация
3 — шаблон
workflowid GUID Уникальный идентификатор для облачного потока среди всех импортов.
workflowidunique GUID Уникальный идентификатор для этой установки потока.

Заметка

В веб-API значения подстановки представляют собой однозначные свойства навигации, которые можно расширить, чтобы получить сведения из связанной записи.

Столбцы подстановки также имеют соответствующие свойства подстановки GUID, которые можно использовать в запросах. Свойства подстановки имеют следующее соглашение об именовании: _<logical name>_value. Для типа сущности рабочего процесса в веб-API вы можете ссылаться на следующие свойства подстановки: _createdby_value, _modifiedby_value и _ownerid_value.

Показать список потоков

Чтобы получить список облачных потоков, вы можете запросить таблицу рабочего процесса. Следующий запрос возвращает первый автоматический, мгновенный или запланированный поток, который в данный момент включен:

Для статического метода OutputFirstActiveFlow требуется аутентифицированный клиент, реализующий метод IOrganizationService. Он использует метод IOrganizationService.RetrieveMultiple.

/// <summary>
/// Outputs the first active flow
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
public static void OutputFirstActiveFlow(IOrganizationService service)
{
   var query = new QueryExpression("workflow")
   {
         ColumnSet = new ColumnSet("category",
                                    "createdby",
                                    "createdon",
                                    "description",
                                    "ismanaged",
                                    "modifiedby",
                                    "modifiedon",
                                    "name",
                                    "ownerid",
                                    "statecode",
                                    "type",
                                    "workflowid",
                                    "workflowidunique"),
         Criteria = new FilterExpression(LogicalOperator.And)
         {
            Conditions = {
            {  new ConditionExpression(
               "category",
                     ConditionOperator.Equal,
                     5) }, // Cloud Flow
            {  new ConditionExpression(
                     "statecode",
                     ConditionOperator.Equal,
                     1) } // Active
         }
         },
         TopCount = 1 // Limit to one record
   };

   EntityCollection workflows = service.RetrieveMultiple(query);

   Entity workflow = workflows.Entities.FirstOrDefault();

   Console.WriteLine($"category: {workflow.FormattedValues["category"]}");
   Console.WriteLine($"createdby: {workflow.FormattedValues["createdby"]}");
   Console.WriteLine($"createdon: {workflow.FormattedValues["createdon"]}");
   // Description may be null
   Console.WriteLine($"description: {workflow.GetAttributeValue<string>("description")}");
   Console.WriteLine($"ismanaged: {workflow.FormattedValues["ismanaged"]}");
   Console.WriteLine($"modifiedby: {workflow.FormattedValues["modifiedby"]}");
   Console.WriteLine($"modifiedon: {workflow.FormattedValues["modifiedon"]}");
   Console.WriteLine($"name: {workflow["name"]}");
   Console.WriteLine($"ownerid: {workflow.FormattedValues["ownerid"]}");
   Console.WriteLine($"statecode: {workflow.FormattedValues["statecode"]}");
   Console.WriteLine($"type: {workflow.FormattedValues["type"]}");
   Console.WriteLine($"workflowid: {workflow["workflowid"]}");
   Console.WriteLine($"workflowidunique: {workflow["workflowidunique"]}");
}

Чтобы получить больше записей, снимите ограничение TopCount.

Выходные данные

category: Modern Flow
createdby: SYSTEM
createdon: 5/20/2020 9:37 PM
description:
ismanaged: Unmanaged
modifiedby: Kiana Anderson
modifiedon: 5/6/2023 3:37 AM
name: When an account is updated -> Create a new record
ownerid: Monica Thomson
statecode: Activated
type: Definition
workflowid: d9e875bf-1c9b-ea11-a811-000d3a122b89
workflowidunique: c17af45c-10a1-43ca-b816-d9cc352718cf

Подробнее:

Создание облачного потока

Требуемые свойства для автоматических, мгновенных и запланированных потоков: category, name, type, primaryentity и clientdata. Используйте none для primaryentity у этих типов потоков.

Для этого статического метода требуется аутентифицированный клиент, реализующий метод IOrganizationService. Он использует метод IOrganizationService.Create.

/// <summary>
/// Creates a cloud flow
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <returns>The workflowid</returns>
public static Guid CreateCloudFlow(IOrganizationService service)
{
   var workflow = new Entity("workflow")
   {
         Attributes = {
            {"category", new OptionSetValue(5) }, // Cloud flow
            {"name", "Sample flow name"},
            {"type", new OptionSetValue(1) }, //Definition
            {"description", "This flow reads some data from Dataverse." },
            {"primaryentity", "none" },
            {"clientdata", "{\"properties\":{\"connectionReferences\":{\"shared_commondataserviceforapps\":{\"impersonation\":{},\"runtimeSource\":\"embedded\",\"connection\":{\"name\":\"shared-commondataser-114efb88-a991-40c7-b75f-2693-b1ca6a0c\",\"connectionReferenceLogicalName\":\"crdcb_sharedcommondataserviceforapps_109ea\"},\"api\":{\"name\":\"shared_commondataserviceforapps\"}}},\"definition\":{\"$schema\":\"https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#\",\"contentVersion\":\"1.0.0.0\",\"parameters\":{\"$connections\":{\"defaultValue\":{},\"type\":\"Object\"},\"$authentication\":{\"defaultValue\":{},\"type\":\"SecureObject\"}},\"triggers\":{\"manual\":{\"metadata\":{\"operationMetadataId\":\"76f87a86-89b3-48b4-92a2-1b74539894a6\"},\"type\":\"Request\",\"kind\":\"Button\",\"inputs\":{\"schema\":{\"type\":\"object\",\"properties\":{},\"required\":[]}}}},\"actions\":{\"List_rows\":{\"runAfter\":{},\"metadata\":{\"operationMetadataId\":\"9725b30f-4a8e-4695-b6fd-9a4985808809\"},\"type\":\"OpenApiConnection\",\"inputs\":{\"host\":{\"apiId\":\"/providers/Microsoft.PowerApps/apis/shared_commondataserviceforapps\",\"connectionName\":\"shared_commondataserviceforapps\",\"operationId\":\"ListRecords\"},\"parameters\":{\"entityName\":\"accounts\",\"$select\":\"name\",\"$top\":1},\"authentication\":\"@parameters('$authentication')\"}}}}},\"schemaVersion\":\"1.0.0.0\"}" }
         }
   };

   return service.Create(workflow);
}

Дополнительная информация: Создание строк таблицы с помощью службы организации

Для statecode всех потоков, созданных таким образом, задается значение 0 ("Черновик" или "Выкл."). Поток должен быть включен, прежде чем его можно будет использовать.

Наиболее важное свойство — clientdata. Оно содержит connectionReferences, которые использует поток, и определение потока. В connectionReferences приведено сопоставление для каждого подключения, используемого потоком.

{
  "properties": {
    "connectionReferences": {
      "shared_commondataserviceforapps": {
        "runtimeSource": "embedded",
        "connection": {},
        "api": { 
         "name": "shared_commondataserviceforapps" 
         }
      }
    },
    "definition": {
      "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "$connections": { "defaultValue": {}, "type": "Object" },
        "$authentication": { "defaultValue": {}, "type": "SecureObject" }
      },
      "triggers": {
        "manual": {
          "metadata": {},
          "type": "Request",
          "kind": "Button",
          "inputs": {
            "schema": { "type": "object", "properties": {}, "required": [] }
          }
        }
      },
      "actions": {
        "List_rows": {
          "runAfter": {},
          "metadata": {},
          "type": "OpenApiConnection",
          "inputs": {
            "host": {
              "apiId": "/providers/Microsoft.PowerApps/apis/shared_commondataserviceforapps",
              "connectionName": "shared_commondataserviceforapps",
              "operationId": "ListRecords"
            },
            "parameters": {
              "entityName": "accounts",
              "$select": "name",
              "$top": 1
            },
            "authentication": "@parameters('$authentication')"
          }
        }
      }
    }
  },
  "schemaVersion": "1.0.0.0"
}

Обновление облачного потока

Чтобы обновить поток, задайте только те свойства, которые хотите изменить.

Для этого статического метода требуется аутентифицированный клиент, реализующий метод IOrganizationService. Он использует метод IOrganizationService.Update для обновления описания потока и установки владельца.

/// <summary>
/// Updates a cloud flow
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <param name="workflowid">The ID of the flow to update.</param>
/// <param name="systemuserid">The id of the user to assign the flow to.</param>
public static void UpdateCloudFlow(IOrganizationService service, Guid workflowid, Guid systemuserid) {

   var workflow = new Entity("workflow",workflowid)
   {
         Attributes = {

            {"description", "This flow will ensure consistency across systems." },
            {"ownerid", new EntityReference("systemuser",systemuserid)},
            {"statecode", new OptionSetValue(1) } //Turn on the flow.
         }
   };

   service.Update(workflow);
}

Дополнительная информация: Обновление и удаление строк таблицы с помощью службы организации > базового обновления

Удаление облачного потока

В следующих примерах показано, как удалить запись рабочего процесса, представляющую облачный поток.

Статический метод DeleteCloudFlow удаляет запись рабочего процесса.

/// <summary>
/// Deletes a workflow
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <param name="workflowId">The id of the cloud flow to delete.</param>
public static void DeleteCloudFlow(IOrganizationService service, Guid workflowId) { 

service.Delete(entityName:"workflow",id: workflowId);

}

Дополнительные сведения: Удаление записи с помощью пакета SDK

Получение списка всех пользователей, которым предоставлен общий доступ к облачному потоку

Используйте сообщение RetrieveSharedPrincipalsAndAccess, чтобы получить список всех пользователей, которым предоставлен общий доступ к облачному потоку.

С помощью пакета SDK используйте класс RetrieveSharedPrincipalsAndAccessRequest, а с помощью веб-API используйте функцию RetrieveSharedPrincipalsAndAccess.

Дополнительная информация: Получение субъектов с доступом к записи

Включение или отмена общего доступа к облачному потоку

Вы можете поделиться облачным потоком, как и любой другой записью Dataverse, используя сообщение GrantAccess. С помощью пакета SDK используйте класс GrantAccessRequest, а с помощью веб-API используйте действие GrantAccess. Дополнительные сведения: Пример GrantAccess

Если вы хотите изменить права доступа, которые вы предоставляете при совместном использовании записи, используйте сообщение ModifyAccess. С помощью пакета SDK используйте класс ModifyAccessRequest, а с помощью веб-API используйте действие ModifyAccess. Дополнительные сведения: Пример ModifyAccess

Чтобы закрыть доступ к записи, используйте сообщение RevokeAccess. С помощью пакета SDK используйте класс RevokeAccessRequest, а с помощью веб-API используйте действие RevokeAccess. Дополнительные сведения: Отзыв доступа

Экспорт потоков

Если поток является частью решения, вы можете экспортировать его, экспортировав решение, содержащее поток, с помощью сообщения ExportSolution.

Приведенный ниже пример статического метода ExportSolution использует ExportSolutionRequest для получения byte[], содержащего ZIP-файл неуправляемого решения с указанным уникальным именем UniqueName.

/// <summary>
/// Exports an unmanaged solution
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <param name="solutionUniqueName">The uniquename of the solution.</param>
/// <returns></returns>
public static byte[] ExportSolution(
   IOrganizationService service, 
   string solutionUniqueName) 
{
   ExportSolutionRequest request = new() { 
         SolutionName = solutionUniqueName,
         Managed = false
   };

   var response = (ExportSolutionResponse)service.Execute(request);

   return response.ExportSolutionFile;
}

Импорт потоков

Если у вас есть ZIP-файл решения, вы можете импортировать его с помощью сообщения ImportSolution.

При импорте потоков необходимо задать следующие параметры:

Имя свойства Описание:
OverwriteUnmanagedCustomizations Если в Dataverse есть существующие экземпляры этих потоков, необходимо задать этот флаг как true для их импорта. В противном случае они не перезаписываются.
PublishWorkflows Указывает, будут ли активированы классические рабочие процессы Dataverse при импорте. Этот параметр не применяется к другим типам потоков.
CustomizationFile ZIP-файл в кодировке Base64, содержащий решение.

Пример статического метода ImportSolution показывает, как импортировать файл решения с помощью класса ImportSolutionRequest

/// <summary>
/// Imports a solution.
/// </summary>
/// <param name="service">Authenticated client implementing the IOrganizationService interface</param>
/// <param name="solutionFile">The byte[] data representing a solution file. </param>
public static void ImportSolution(
   IOrganizationService service, 
   byte[] solutionFile) {

   ImportSolutionRequest request = new() { 
         OverwriteUnmanagedCustomizations = true,
         CustomizationFile = solutionFile
   };

   service.Execute(request);
}

См. также

Операции класса Entity, использующие службу организации
Выполнение операций с помощью веб-API
Совместное использование и назначение
Проверка доступа в коде
Работа с решениями с помощью пакета SDK Dataverse