Condividi tramite


Aggiungere ed eseguire script C# inline con flussi di lavoro Standard per App per la logica di Azure (anteprima)

Si applica: App per la logica di Azure (Standard)

Nota

Questa funzionalità è in anteprima ed è soggetta alle Condizioni supplementari per l'utilizzo per le anteprime di Microsoft Azure.

Per eseguire attività di integrazione personalizzate inline con il flusso di lavoro Standard in App per la logica di Azure, è possibile aggiungere ed eseguire direttamente script C# dall'interno del flusso di lavoro. Per questa attività, usare l'azione Codice inline denominata Esegui codice script CSharp. Questa azione restituisce i risultati dello script in modo che sia possibile usare questo output nelle azioni successive del flusso di lavoro.

Questa funzionalità offre i vantaggi seguenti:

  • Scrivere script personalizzati all'interno della finestra di progettazione del flusso di lavoro in modo da poter risolvere problemi di integrazione più complessi senza dover usare Funzioni di Azure. Non sono necessari altri piani di servizio.

    Questo vantaggio semplifica lo sviluppo del flusso di lavoro e riduce la complessità e i costi con la gestione di più servizi.

  • Generare un file di codice dedicato, che fornisce uno spazio di scripting personalizzato all'interno del flusso di lavoro.

  • Distribuire il codice insieme ai flussi di lavoro.

Questa guida illustra come aggiungere l'azione nel flusso di lavoro e aggiungere il codice script C# da eseguire.

Prerequisiti

  • Account e sottoscrizione di Azure. Se non si ha una sottoscrizione, è possibile iscriversi per creare un account Azure gratuito.

  • Flusso di lavoro dell'app per la logica Standard in cui si vuole aggiungere lo script C#. Il flusso di lavoro deve già iniziare con un trigger. Per altre informazioni, vedere Creare flussi di lavoro dell'app per la logica Standard.

    È possibile usare qualsiasi trigger per lo scenario, ma, ad esempio, questa guida usa il trigger Richiesta denominato Quando viene ricevuta una richiesta HTTP e anche l'azione Risposta. Il flusso di lavoro viene eseguito quando un'altra applicazione o flusso di lavoro invia una richiesta all'URL dell'endpoint del trigger. Lo script di esempio restituisce i risultati dell'esecuzione del codice come output che è possibile usare nelle azioni successive.

Scenari di esempio

L'elenco seguente descrive alcuni scenari di esempio in cui è l'uso di uno script aiuta con determinate attività di integrazione:

  • Analizzare ed eseguire trasformazioni o manipolazioni su un payload oltre alle funzionalità predefinite di espressioni e operazioni sui dati. Ad esempio, è possibile usare uno script per restituire uno schema modificato per l'elaborazione downstream.

  • Gestire le risorse di Azure, ad esempio le macchine virtuali, e avviarle o eseguirne il passaggio, in base a una logica di business.

  • Eseguire una stored procedure in un server SQL che deve essere eseguito in base a una pianificazione e archiviare i risultati in SharePoint.

  • Registrare gli errori del flusso di lavoro con informazioni dettagliate salvando il tutto in Archiviazione di Azure per poi inviare un'e-mail o avvisare il team in altro modo.

  • Crittografare e decrittografare i dati per rispettare gli standard di sicurezza delle API.

  • Passare un file nello script per comprimere o decomprimere una richiesta HTTP.

  • Aggregare i dati da varie API e file per creare report giornalieri

Considerazioni

  • Il portale di Azure salva lo script come file di script C# (con estensione csx) nella stessa cartella del file workflow.json, che archivia la definizione JSON per il flusso di lavoro e distribuisce il file nella risorsa dell'app per la logica insieme alla definizione del flusso di lavoro. App per la logica di Azure compila questo file per rendere lo script pronto per l'esecuzione.

    Il formato di file con estensione csx consente di scrivere meno "boilerplate" e di concentrarsi solo sulla scrittura di una funzione C#. È possibile rinominare il file con estensione csx per semplificare la gestione durante la distribuzione. Tuttavia, ogni volta che si rinomina lo script, la nuova versione sovrascrive la versione precedente.

  • Lo script è locale per il flusso di lavoro. Per usare lo stesso script in altri flussi di lavoro, visualizzare il file di script nella console kuduPluse quindi copiare lo script da riutilizzare in altri flussi di lavoro.

Limiti

Nome Limit Note
Durata esecuzione script 10 minuti Se si hanno scenari che richiedono durate più lunghe, usare l'opzione di feedback del prodotto per fornire altre informazioni sulle proprie esigenze.
Dimensioni di output 100 MB Le dimensioni dell'output dipendono dal limite di dimensioni di output per le azioni, che in genere è di 100 MB.

Aggiungere l'azione Esegui codice script CSharp

  1. Nel portale di Azure aprire la risorsa e il flusso di lavoro dell'app per la logica Standard nella finestra di progettazione.

  2. Nella finestra di progettazione seguire questa procedura generale per aggiungere l'azione Operazioni codice inline denominata Esegui codice script CSharp al flusso di lavoro.

  3. Dopo aver aperto il riquadro informazioni sull'azione, nella scheda Parametri aggiornare il codice di esempio prepopolato con il proprio codice script nella casella File di codice.

    L'esempio seguente mostra la scheda Parametri dell'azione con il codice script di esempio:

    Screenshot che mostra il portale di Azure, la finestra di progettazione del flusso di lavoro Standard, il trigger di richiesta, l'azione Esegui codice script CSharp con il riquadro informazioni aperto e Azione di risposta. Il riquadro informazioni mostra lo script C# di esempio.

    L'esempio seguente illustra il codice di script di esempio:

    /// 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;}
    }
    

    Per altre informazioni, vedere "#r" - Riferimenti ad assembly esterni.

  4. Al termine, salvare il flusso di lavoro.

Dopo aver eseguito il flusso di lavoro, è possibile esaminare l'output del flusso in Application Insights, se abilitato. Per altre informazioni, vedere Visualizza log in Application Insights.

Importa spazi dei nomi

Per importare gli spazi dei nomi, eseguire questa operazione con la clausola using come di consueto. L'elenco seguente include spazi dei nomi importati automaticamente, che quindi sono facoltativi da includere nello script:

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

Aggiungere riferimenti ad assembly esterni

Per fare riferimento agli assembly .NET Framework, usare la direttiva #r "<assembly-name>, ad esempio:

/// 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)
{
    <...>
}

public class Results
{
    <...>
}

L'elenco seguente include gli assembly aggiunti automaticamente dall'ambiente di hosting di Funzioni di Azure:

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

Registrare l'output in un flusso

Nel metodo Run includere un parametro con tipo ILogger e log come nome, ad esempio:

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

Registrare l'output in Application Insights

Per creare metriche personalizzate in Application Insights, usare il metodo di estensione LogMetric in ILogger.

L'esempio seguente mostra una chiamata di metodo di esempio:

logger.LogMetric("TestMetric", 1234);

Accedere agli output di trigger e azioni del flusso di lavoro nello script

Per accedere ai dati dal flusso di lavoro, usare i metodi seguenti disponibili per l'oggetto contesto WorkflowContext:

  • Metodo GetTriggerResults

    Per accedere agli output dei trigger, utilizzare questo metodo per restituire un oggetto che rappresenta il trigger e i relativi output, disponibili tramite la proprietà Outputs. Questo oggetto ha il tipo JObject ed è possibile usare le parentesi quadre ([]) come indicizzatore per accedere a varie proprietà negli output del trigger.

    L'esempio seguente ottiene i dati dalla proprietà body negli output del trigger:

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

    Per accedere agli output delle azioni, utilizzare questo metodo per restituire un oggetto che rappresenta l'azione e i relativi output, disponibili tramite la proprietà Outputs. Questo metodo accetta un nome di azione come parametro. L'esempio seguente ottiene i dati dalla proprietà body negli output da un'azione denominata action-name:

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

Accedere alle variabili di ambiente o al valore dell'impostazione dell'app

Per ottenere una variabile di ambiente o un valore di impostazione dell'app, usare ad esempio il metodo 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);
}

Restituire i dati al flusso di lavoro

Per questa attività, implementare il metodo Run con un tipo restituito e un'istruzione return. Se si desidera una versione asincrona, implementare il metodo Run con un attributo Task<return-type> e la parola chiave async. Il valore restituito viene impostato sulla proprietà body degli output dell'azione script, a cui possono quindi fare riferimento le azioni successive del flusso di lavoro.

Nell'esempio seguente viene illustrato un metodo Run con un attributo Task<Results>, la parola chiave async e un'istruzione return:

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;}
}

Visualizzare il file di script

  1. Nel portale di Azure aprire la risorsa dell'app per la logica Standard con il flusso di lavoro desiderato.

  2. Nel menu delle risorse dell'app per la logica, in Strumenti di sviluppo selezionare Strumenti avanzati.

  3. Nella pagina Strumenti avanzati selezionare Vai, che apre la console di KuduPlus.

  4. Aprire il menu Console di debug e selezionare CMD.

  5. Passare alla posizione radice dell'app per la logica: site/wwwroot

  6. Passare alla cartella del flusso di lavoro, che contiene il file con estensione csx, lungo questo percorso: site/wwwroot/{workflow-name}

  7. Accanto al nome del file selezionare Modifica per aprire e visualizzare il file.

Visualizzare i log in Application Insights

  1. Nel portale di Azure, nel menu delle risorse dell'app per la logica, in Impostazioni selezionare Application Insights e quindi selezionare l'app per la logica.

  2. Nel menu Application Insights, in Monitoraggio selezionare Log.

  3. Creare una query per trovare tracce o errori dall'esecuzione del flusso di lavoro, ad esempio:

    union traces, errors
    | project TIMESTAMP, message
    

Errori di compilazione

In questa versione, l'editor basato sul Web include un supporto IntelliSense limitato, che è ancora in fase di miglioramento. Eventuali errori di compilazione vengono rilevati quando si salva il flusso di lavoro e il runtime di App per la logica di Azure compila lo script. Questi errori vengono visualizzati nei log degli errori dell'app per la logica.

Errori di runtime

Se si verifica un errore quando viene eseguito lo script, App per la logica di Azure esegue questi passaggi:

  • Passa di nuovo l'errore al flusso di lavoro.
  • Contrassegna l'azione script come Non riuscito.
  • Fornisce un oggetto errore che rappresenta l'eccezione generata dallo script.

L'esempio seguente riporta un errore di esempio:

La funzione "CSharp_MyLogicApp-InvalidAction_execute_csharp_script_code.csx" non è riuscita con l'errore "L'azione "inesistente" non esiste nel flusso di lavoro." durante l'esecuzione. Verificare che il codice della funzione sia valido.

Script di esempio

Gli script di esempio seguenti eseguono varie attività che è possibile

Decomprimere un file ZIP con file di testo da un'azione HTTP in una matrice di stringhe

// 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;
}

Crittografare i dati usando una chiave dalle impostazioni dell'app

// 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());

        }
    }
}

Classe WorkflowContext

Rappresenta un contesto del flusso di lavoro.

Metodi

GetActionResult(string actionName)

Ottiene il risultato da un'azione specifica nel flusso di lavoro.

La versione asincrona usa Attività<> come tipo restituito, ad esempio:

Task<WorkflowOperationResult> GetActionResult(string actionName)

Parametri

actionName: nome dell'azione.

Valori restituiti

La versione asincrona restituisce un oggetto Task che rappresenta l'operazione asincrona. Il risultato dell'attività contiene un oggetto WorkflowOperationResult. Per informazioni sulle proprietà dell'oggetto WorkflowOperationResult, vedere Classe WorkflowOperationResult.

RunTriggerResult()

Ottiene il risultato dal trigger nel flusso di lavoro.

La versione asincrona usa Attività<> come tipo restituito, ad esempio:

Task<WorkflowOperationResult> RunTriggerResult()

Parametri

Nessuna.

Valori restituiti

La versione asincrona restituisce un oggetto Task che rappresenta l'operazione asincrona. Il risultato dell'attività contiene un oggetto WorkflowOperationResult. Per informazioni sulle proprietà dell'oggetto WorkflowOperationResult, vedere Classe WorkflowOperationResult.

Classe WorkflowOperationResult

Rappresenta il risultato di un'operazione del flusso di lavoro.

Proprietà

Nome Tipo Descrizione
Nome string Ottiene o imposta il nome dell'operazione.
Input JToken Ottiene o imposta gli input di esecuzione dell'operazione.
Output JToken Ottiene o imposta gli output di esecuzione dell'operazione.
StartTime DateTime? Ottiene o imposta l'ora di inizio dell'operazione.
EndTime DateTime? Ottiene o imposta l'ora di fine dell'operazione.
OperationTrackingId String Ottiene o imposta l'ID di traccia dell'operazione.
Codice String Ottiene o imposta il codice di stato per l'azione.
Stato String Ottiene o imposta lo stato dell'azione.
Errore JToken Ottiene o imposta l'errore per l'azione.
TrackedProperties JToken Ottiene o imposta le proprietà rilevate per l'azione.

Aggiungere ed eseguire frammenti di codice JavaScript