共用方式為


使用 Azure Logic Apps 的標準工作流程內嵌新增並執行 C# 腳稿 (預覽)

適用於:Azure Logic Apps (標準)

注意

此功能處於預覽狀態,且受限於 Microsoft Azure 預覽版的補充使用規定

若要在 Azure Logic Apps 中搭配標準工作流程內嵌執行自定義整合工作,您可以在 Azure 入口網站 中直接從工作流程新增並執行簡單的 C# 腳本。 針對這項工作,請使用名為 Execute CSharp Script Code 的內嵌程式代碼動作。 此動作會從腳本傳回結果,讓您可以在工作流程的後續動作中使用該輸出。

這項功能提供下列優點:

  • 撰寫您自己的腳本來解決更複雜的整合問題,而不需要使用 Azure Functions。

    這項優點可簡化工作流程開發,並降低管理更多服務的複雜性和成本。

  • 將腳本與工作流程一起部署。 不需要其他服務方案。

本指南說明如何在工作流程中新增動作,並新增您想要執行的 C# 腳本程序代碼。

必要條件

  • Azure 帳戶和訂用帳戶。 如果您沒有訂用帳戶,請註冊一個免費的 Azure 帳戶

  • 您想要在其中新增 C# 文稿的標準邏輯應用程式工作流程。 工作流程必須已經從觸發程序開始。 如需詳細資訊,請參閱 建立範例標準邏輯應用程式工作流程

    您可以針對您的案例使用任何觸發程式,但舉例來說,本指南會使用名為「收到 HTTP 要求時」的要求觸發程式,以及響應動作。 當另一個應用程式或工作流程將要求傳送至觸發程式的端點 URL 時,工作流程就會執行。 範例腳本會傳回程式代碼執行的結果,做為您可以在後續動作中使用的輸出。

範例案例

下列清單說明一些範例案例,您可以在其中使用腳本來協助執行特定整合工作:

  • 剖析和執行承載的轉換或操作,超出內建運算式和數據作業功能。 例如,您可以使用腳本傳回已修改的架構以進行下游處理。

  • 根據某些商業規則管理 Azure 資源,例如虛擬機並啟動或逐步執行。

  • 在需要排程執行的 SQL 伺服器上執行預存程式,並將結果儲存在 SharePoint 上。

  • 藉由儲存至 Azure 儲存體 或傳送電子郵件或通知小組,記錄具有詳細資訊的工作流程錯誤。

  • 加密和解密數據以符合 API 安全性標準。

  • 將檔案傳遞至腳本,以壓縮或解壓縮 HTTP 要求。

  • 匯總來自各種 API 和檔案的數據,以建立每日報告

考量

  • Azure 入口網站 會將腳本儲存為 C# 腳本檔案 (.csx),該檔案會儲存在與workflow.json檔案相同的資料夾中,以儲存工作流程的 JSON 定義,並將檔案連同工作流程定義一起部署到邏輯應用程式資源。 Azure Logic Apps 會編譯此檔案,讓腳本準備好執行。

    .csx 檔格式可讓您撰寫較少的「重複使用」,並專注於撰寫 C# 函式。 您可以重新命名 .csx 檔案,以在部署期間更容易管理。 不過,每次重新命名腳本時,新版本都會覆寫舊版。

  • 腳本是工作流程的本機。 若要在其他工作流程中使用相同的腳本,請在 KuduPlus 主控台檢視腳本檔案,然後複製腳本以在其他工作流程中重複使用。

限制

名稱 限制 備註
腳本執行持續時間 10 分鐘 如果您有需要較長持續時間的案例,請使用產品意見反應選項來提供您需求的詳細資訊。
輸出大小 100 MB 輸出大小取決於動作的輸出大小限制,這通常為100 MB。

新增執行 CSharp 指令本程式代碼動作

  1. Azure 入口網站,於設計工具中開啟您的標準邏輯應用程式資源和工作流程。

  2. 在設計工具中,遵循下列一般步驟,將名為 Execute CSharp Script Code 動作的內嵌程式代碼作業動作新增至您的工作流程

  3. 動作資訊窗格開啟之後,在 [ 參數 ] 索引卷標的 [程序代碼檔案 ] 方塊中,使用您自己的腳本程式代碼更新預先填入的範例程序代碼。

    下列範例顯示動作的 [參數 ] 索引標籤,其中包含範例腳本程序代碼:

    此螢幕快照顯示 Azure 入口網站、標準工作流程設計工具、要求觸發程式、開啟資訊窗格和執行 CSharp 腳本程式代碼動作。資訊窗格會顯示範例 C# 腳本。

    下列範例顯示範例文稿程式代碼:

    /// Add the required libraries.
    #r "Newtonsoft.Json"
    #r "Microsoft.Azure.Workflows.Scripting"
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Primitives;
    using Microsoft.Extensions.Logging;
    using Microsoft.Azure.Workflows.Scripting;
    using Newtonsoft.Json.Linq;
    
    /// <summary>
    /// Executes the inline C# code.
    /// </summary>
    /// <param name="context">The workflow context.</param>
    /// <remarks> The entry-point to your code. The function signature should remain unchanged.</remarks>
    public static async Task<Results> Run(WorkflowContext context, ILogger log)
    {
        var triggerOutputs = (await context.GetTriggerResults().ConfigureAwait(false)).Outputs;
    
        /// Dereferences the 'name' property from the trigger payload.
        var name = triggerOutputs?["body"]?["name"]?.ToString();
    
        /// To get the outputs from a preceding action, you can uncomment and repurpose the following code.
        //var actionOutputs = (await context.GetActionResults("<action-name>").ConfigureAwait(false)).Outputs;
    
        /// The following logs appear in the Application Insights traces table.
        //log.LogInformation("Outputting results.");
    
        /// var name = null;
    
        return new Results
        {
            Message = !string.IsNullOrEmpty(name) ? $"Hello {name} from CSharp action" : "Hello from CSharp action."
        };
    }
    
    public class Results
    {
        public string Message {get; set;}
    }
    

    如需詳細資訊,請參閱 <#r - 參考外部元件>

  4. 完成後,請儲存您的工作流程。

檢視腳本檔案

  1. Azure 入口網站 中,開啟具有所需工作流程的標準邏輯應用程序資源。

  2. 在邏輯應用程式資源功能表上的 [開發工具] 底下,選取 [進階工具]。

  3. 在 [ 進階工具] 頁面上,選取 [Go],這會開啟 KuduPlus 控制台。

  4. 開啟 [偵 錯控制台] 功能表,然後選取 [ CMD]。

  5. 移至邏輯應用程式的根位置: site/wwwroot

  6. 移至工作流程的資料夾,其中包含 .csx 檔案,沿著此路徑: site/wwwroot/{workflow-name}

  7. 在檔名旁邊,選取 [ 編輯 ] 以開啟並檢視檔案。

匯入命名空間

若要匯入命名空間,請像往常一樣使用 using 子句。 下列清單包含自動匯入的命名空間,因此您可以選擇性地包含在腳本中:

System
System.Collections.Generic
System.IO
System.Linq
System.Net.Http
System.Threading.Tasks
Microsoft.Azure.WebJobs
Microsoft.Azure.WebJobs.Host

新增外部元件的參考

若要參考 .NET Framework 元件,請使用 #r "<assembly-name> 指示詞,例如:

/// Add the required libraries.
#r "Newtonsoft.Json"
#r "Microsoft.Azure.Workflows.Scripting"
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Microsoft.Extensions.Logging;
using Microsoft.Azure.Workflows.Scripting;
using Newtonsoft.Json.Linq;
public static async Task<Results> Run(WorkflowContext context, ILogger log)

下列清單包含 Azure Functions 裝載環境自動新增的元件:

mscorlib
System
System.Core
System.Xml
System.Net.Http
Microsoft.Azure.WebJobs
Microsoft.Azure.WebJobs.Host
Microsoft.Azure.WebJobs.Extensions
System.Web.Http
System.Net.Http.Formatting
Newtonsoft.Json

存取文稿中的工作流程觸發程式和動作輸出

若要從工作流程存取數據,請使用適用於內容物件的下列方法 WorkflowContext

  • GetTriggerResults 方法

    若要存取觸發程序輸出,請使用此方法傳回 物件,此物件代表觸發程式和其輸出,這些輸出可透過 Outputs 屬性取得。 此物件具有 JObject 類型,而且您可以使用方括弧 ([]) 索引器來存取觸發程序輸出中的各種屬性。

    例如,下列範例程式代碼會從 body 觸發程序輸出中的 屬性取得數據:

    public static async Task<Results> Run(WorkflowContext context, ILogger log)
    {
        var triggerOutputs = (await context.GetTriggerResults().ConfigureAwait(false)).Outputs;
        var body = triggerOutputs["body"];
    }
    
  • GetActionResults 方法

    若要存取動作輸出,請使用這個方法傳回物件,此物件代表動作及其輸出,這些輸出可透過 Outputs 屬性取得。 這個方法接受動作名稱做為參數,例如:

    public static async Task<Results> Run(WorkflowContext context, ILogger log)
    {
    
        var actionOutputs = (await context.GetActionResults("actionName").ConfigureAwait(false)).Outputs;
        var body = actionOutputs["body"];
    }
    

存取環境變數或應用程式設定值

若要取得環境變數或應用程式設定值,請使用 System.Environment.GetEnvironmentVariable 方法,例如:

public static void Run(WorkflowContext context, ILogger log)
{
    log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
    log.LogInformation(GetEnvironmentVariable("AzureWebJobsStorage"));
    log.LogInformation(GetEnvironmentVariable("WEBSITE_SITE_NAME"));
}

public static string GetEnvironmentVariable(string name)
{
    return name + ": " +
    System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
}

將數據傳回您的工作流程

針對這項工作,請使用傳回類型實作您的 Run 方法。 如果您想要異步版本,請實 Run 作 方法做為 Task<>,並將傳回值設定為腳本動作的輸出主體,然後任何後續工作流程動作都可以參考。

public static void Run(WorkflowContext context, ILogger log)
{
    return new Results
    {
        Message = !string.IsNullOrEmpty(name) ? $"Returning results with status message."
    };
}

public class Results
{
    public string Message {get; set;}
}

-或-

public static async Task<Results> Run(WorkflowContext context, ILogger log)
{
    return new Results
    {
        Message = !string.IsNullOrEmpty(name) ? $"Returning results with status message."
    };
}

public class Results
{
    public string Message {get; set;}
}

將輸出記錄至數據流

在您的 Run 方法中,包含類型為 ILoggerlog 的參數作為名稱,例如:

public static void Run(WorkflowContext context, ILogger log)
{
    log.LogInformation($"C# script successfully executed.");
}

將輸出記錄至 Application Insights

若要在 Application Insights 中建立自定義計量,請在 LogMetric 上使用 ILogger擴充方法。

下列範例顯示範例方法呼叫:

logger.LogMetric("TestMetric", 1234);

編譯錯誤

在此版本中,網頁型編輯器包含有限的 IntelliSense 支援,其仍在改善中。 當您儲存工作流程時,會偵測到任何編譯錯誤,而 Azure Logic Apps 執行時間會編譯您的腳本。 這些錯誤會出現在邏輯應用程式的錯誤記錄檔中。

執行階段錯誤

如果您的文稿執行時發生錯誤,Azure Logic Apps 會執行下列步驟:

  • 將錯誤傳回您的工作流程。
  • 將腳本動作標示為 [失敗]。
  • 提供錯誤物件,代表從腳本擲回的例外狀況。

下列範例顯示範例錯誤:

函式 'CSharp_MyLogicApp-InvalidAction_execute_csharp_script_code.csx' 失敗,錯誤「工作流程中不存在」動作「不存在」。 執行時。 請確認函式程式碼有效。

範例指令碼

下列範例腳本會執行您可能執行的各種工作

將含有文字檔的 ZIP 檔案從 HTTP 動作解壓縮到字串陣列

// Add the required libraries.
#r "Newtonsoft.Json"
#r "Microsoft.Azure.Workflows.Scripting"
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Microsoft.Azure.Workflows.Scripting;
using System;
using System.IO;
using System.IO.Compression;
using System.Text;
using System.Collections.Generic;

/// <summary>
/// Executes the inline C# code.
/// </summary>
/// <param name="context">The workflow context.</param>
public static async Task<List<string>> Run(WorkflowContext context)
{

    var outputs = (await context.GetActionResults("HTTP_1").ConfigureAwait(false)).Outputs;
    var base64zipFileContent = outputs["body"]["$content"].ToString();

    // Decode base64 to bytes.
    byte[] zipBytes = Convert.FromBase64String(base64zipFileContent);

    List<string> fileContents = new List<string>();

    // Creates an in-memory stream from the zip bytes.
    using (MemoryStream zipStream = new MemoryStream(zipBytes))
    {

        // Extracts files from the zip archive.
        using (ZipArchive zipArchive = new ZipArchive(zipStream))
        {

            foreach (ZipArchiveEntry entry in zipArchive.Entries)
            {

                // Read each file's content.
                using (StreamReader reader = new StreamReader(entry.Open()))
                {
                    string fileContent = reader.ReadToEnd();
                    fileContents.Add(fileContent);
                }
            }
        }
    }

    return fileContents;
}

使用來自應用程式設定的金鑰加密資料

// Add the required libraries.
#r "Newtonsoft.Json"
#r "Microsoft.Azure.Workflows.Scripting"
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Microsoft.Azure.Workflows.Scripting;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

/// <summary>
/// Executes the inline csharp code.
/// </summary>
/// <param name="context">The workflow context.</param>
public static async Task<string> Run(WorkflowContext context)
{

    var compose = (await context.GetActionResults("compose").ConfigureAwait(false)).Outputs;
    var text = compose["sampleData"].ToString();

    return EncryptString(text);

}

public static string EncryptString(string plainText)
{

    var key = Environment.GetEnvironmentVariable("app-setting-key");
    var iv = Environment.GetEnvironmentVariable("app-setting-iv");

    using (Aes aesAlg = Aes.Create())
    {

        aesAlg.Key = Encoding.UTF8.GetBytes(key);
        aesAlg.IV = Encoding.UTF8.GetBytes(iv);
        ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

        using (MemoryStream msEncrypt = new MemoryStream())
        {

            using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
            {

                using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                {
                    swEncrypt.Write(plainText);
                }

            }

             return Convert.ToBase64String(msEncrypt.ToArray());

        }
    }
}

WorkflowContext 類別

表示工作流程內容。

方法

GetActionResult(string actionName)

從工作流程中的特定動作取得結果。

異步版本使用 Task<> 做為傳回類型,例如:

Task<WorkflowOperationResult> GetActionResult(string actionName)

參數

actionName:動作名稱。

傳回

異步版本會傳 Task 回 代表異步操作的物件。 工作結果包含 WorkflowOperationResult 物件。 如需 WorkflowOperationResult 物件屬性的相關信息,請參閱 WorkflowOperationResult 類別

RunTriggerResult()

從工作流程中的觸發程式取得結果。

異步版本使用 Task<> 做為傳回類型,例如:

Task<WorkflowOperationResult> RunTriggerResult()

參數

無。

傳回

異步版本會傳 Task 回 代表異步操作的物件。 工作結果包含 WorkflowOperationResult 物件。 如需 WorkflowOperationResult 物件屬性的相關信息,請參閱 WorkflowOperationResult 類別

WorkflowOperationResult 類別

表示工作流程作業的結果。

屬性

名稱 類型​​ Description
名稱 String 取得或設定作業名稱。
輸入 JToken 取得或設定作業執行輸入。
輸出 JToken 取得或設定作業執行輸出。
StartTime DateTime? 取得或設定作業開始時間。
EndTime DateTime? 取得或設定作業結束時間。
OperationTrackingId String 取得或設定作業追蹤標識碼。
程式碼 String 取得或設定動作的狀態代碼。
狀態 String 取得或設定動作的狀態。
錯誤 JToken 取得或設定動作的錯誤。
TrackedProperties JToken 取得或設定動作的追蹤屬性。

新增並執行 JavaScript 代碼段