Creare ed eseguire codice .NET dai flussi di lavoro Standard in App per la logica di Azure
Si applica: App per la logica di Azure (Standard)
Per le soluzioni di integrazione in cui è necessario creare ed eseguire codice .NET dal flusso di lavoro di App per la logica Standard, è possibile usare Visual Studio Code con l'estensione App per la logica di Azure (Standard). Questa estensione offre le funzionalità e i vantaggi seguenti:
- Scrivere codice personalizzato creando funzioni con flessibilità e controllo per risolvere i problemi di integrazione più complessi.
- Eseguire il debug del codice in locale in Visual Studio Code. Eseguire il codice e i flussi di lavoro nella stessa sessione di debug.
- Distribuire il codice insieme ai flussi di lavoro. Non sono necessari altri piani di servizio.
- Supportare gli scenari di migrazione di BizTalk Server in modo da poter spostare in modalità lift-and-shift gli investimenti .NET personalizzati dall'ambiente locale al cloud.
Con la possibilità di scrivere codice personalizzato, è possibile eseguire scenari come i seguenti:
- Implementazione della logica di business personalizzata
- Analisi personalizzata per estrarre informazioni da un messaggio in ingresso
- Convalida dei dati e trasformazioni semplici
- Modellazione dei messaggi per i messaggi in uscita verso un altro sistema, ad esempio un'API
- Calcoli
Questa funzionalità non è adatta per scenari come i seguenti:
- Processi che richiedono più di 10 minuti per l'esecuzione
- Trasformazioni di dati e messaggi di grandi dimensioni
- Scenari complessi di invio in batch e debatching
- Componenti della pipeline di BizTalk Server che implementano lo streaming
Per altre informazioni sulle limitazioni in App per la logica di Azure, vedere Limiti e configurazione - App per la logica di Azure.
Prerequisiti
Account e sottoscrizione di Azure. Se non si ha una sottoscrizione, è possibile iscriversi per creare un account Azure gratuito.
Visual Studio Code più recente con l'estensione App per la logica di Azure (Standard). Per soddisfare questi requisiti, vedere i prerequisiti per Creare flussi di lavoro Standard in App per la logica di Azure a tenant singolo con Visual Studio Code.
La funzionalità delle funzioni personalizzate è attualmente disponibile solo in Visual Studio Code, in esecuzione in un sistema operativo Windows.
La funzionalità delle funzioni personalizzate supporta attualmente la chiamata a .NET Framework e .NET 8 per i flussi di lavoro delle app per la logica ospitata in Azure.
Cartella locale da usare per la creazione del progetto di codice
Limiti
La creazione di funzioni personalizzate non è attualmente disponibile nel portale di Azure. Tuttavia, dopo aver distribuito le funzioni da Visual Studio Code ad Azure, seguire la procedura descritta in Chiamare il codice da un flusso di lavoro per il portale di Azure. È possibile usare l'azione predefinita denominata Chiamare una funzione locale in questa app per la logica per selezionare dalle funzioni personalizzate distribuite ed eseguire il codice. Le azioni successive nel flusso di lavoro possono fare riferimento agli output di queste funzioni, come in qualsiasi altro flusso di lavoro. È possibile visualizzare la cronologia di esecuzione, gli input e gli output dell'azione predefinita.
Le funzioni personalizzate usano un ruolo di lavoro isolato per richiamare il codice nel flusso di lavoro dell'app per la logica. Per evitare conflitti di riferimenti ai pacchetti tra il proprio codice di funzione e il ruolo di lavoro, usare le stesse versioni del pacchetto a cui fa riferimento il ruolo di lavoro. Per l'elenco completo dei pacchetti e le versioni a cui fa riferimento il ruolo di lavoro, vedere Dipendenze del ruolo di lavoro e dei pacchetti.
Creare un progetto di codice
La versione più recente dell'estensione App per la logica di Azure (Standard) per Visual Studio Code include un modello di progetto di codice che offre un'esperienza semplificata per la scrittura, il debug e la distribuzione di codice personalizzato con i flussi di lavoro. Questo modello di progetto crea un file dell'area di lavoro e due progetti di esempio: un progetto per scrivere il codice, l'altro per creare i flussi di lavoro.
Nota
Non è possibile usare la stessa cartella di progetto sia per il codice che per i flussi di lavoro.
Aprire Visual Studio Code. Nella barra attività, selezionare l'icona di Azure. (Tastiera: MAIUSC+ALT+A)
Nella finestra di Azure visualizzata, sulla barra degli strumenti della sezione Area di lavoro, dal menu App per la logica di Azure, scegliere Crea nuova area di lavoro per l'app per la logica.
Nella casella Seleziona cartella, passare a e selezionare la cartella locale creata per il progetto.
Quando viene visualizzata la casella di richiesta Crea nuova area di lavoro per l'app per la logica, specificare un nome per l'area di lavoro:
Questo esempio continua con MyLogicAppWorkspace.
Quando viene visualizzata la casella di richiesta Selezionare un modello di progetto per l'area di lavoro per l'app per la logica, selezionare App per la logica con progetto di codice personalizzato.
Per i flussi di lavoro di app per la logica Standard ospitati in Azure, seguire la richiesta di selezionare .NET Framework o .NET 8.
Seguire le istruzioni successive per specificare i valori di esempio seguenti:
Articolo Valore di esempio Nome della funzione per il progetto di funzioni .NET WeatherForecast Nome dello spazio dei nomi per il progetto di funzioni .NET Contoso.Enterprise Modello flusso di lavoro:
- Flusso di lavoro con stato
- Flusso di lavoro senza statoFlusso di lavoro con stato Nome flusso di lavoro MyWorkflow Selezionare Apri nella finestra corrente.
Al termine di questo passaggio, Visual Studio Code crea l'area di lavoro, che include un progetto di funzioni .NET e un progetto di app per la logica, ad esempio:
Nodo Descrizione <workspace-name> Contiene sia il progetto di funzioni .NET, che il progetto del flusso di lavoro dell'app per la logica. Funzioni Contiene gli artefatti per il progetto di funzioni .NET. Ad esempio, il <file function-name>.cs è il file di codice in cui è possibile creare il codice. App per la logica Contiene gli artefatti per il progetto dell'app per la logica, incluso un flusso di lavoro vuoto.
Scrivere il codice
Nell'area di lavoro espandere il nodo Funzioni, se non è già espanso.
Aprire il <file function-name>.cs denominato WeatherForecast.cs in questo esempio.
Per impostazione predefinita, questo file contiene codice di esempio con gli elementi di codice seguenti, insieme ai valori di esempio forniti in precedenza, se appropriati:
- Nome spazio dei nomi
- Nome classe
- Nome della funzione
- Parametri di funzione
- Tipo restituito
- Tipo complesso
L'esempio seguente mostra il codice di esempio completo:
//------------------------------------------------------------ // Copyright (c) Microsoft Corporation. All rights reserved. //------------------------------------------------------------ namespace Contoso.Enterprise { using System; using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.Azure.Functions.Extensions.Workflows; using Microsoft.Azure.WebJobs; using Microsoft.Extensions.Logging; /// <summary> /// Represents the WeatherForecast flow invoked function. /// </summary> public class WeatherForecast { private readonly ILogger<WeatherForecast> logger; public WeatherForecast(ILoggerFactory loggerFactory) { logger = loggerFactory.CreateLogger<WeatherForecast>(); } /// <summary> /// Executes the logic app workflow. /// </summary> /// <param name="zipCode">The zip code.</param> /// <param name="temperatureScale">The temperature scale (e.g., Celsius or Fahrenheit).</param> [FunctionName("WeatherForecast")] public Task<Weather> Run([WorkflowActionTrigger] int zipCode, string temperatureScale) { this.logger.LogInformation("Starting WeatherForecast with Zip Code: " + zipCode + " and Scale: " + temperatureScale); // Generate random temperature within a range based on the temperature scale Random rnd = new Random(); var currentTemp = temperatureScale == "Celsius" ? rnd.Next(1, 30) : rnd.Next(40, 90); var lowTemp = currentTemp - 10; var highTemp = currentTemp + 10; // Create a Weather object with the temperature information var weather = new Weather() { ZipCode = zipCode, CurrentWeather = $"The current weather is {currentTemp} {temperatureScale}", DayLow = $"The low for the day is {lowTemp} {temperatureScale}", DayHigh = $"The high for the day is {highTemp} {temperatureScale}" }; return Task.FromResult(weather); } /// <summary> /// Represents the weather information for WeatherForecast. /// </summary> public class Weather { /// <summary> /// Gets or sets the zip code. /// </summary> public int ZipCode { get; set; } /// <summary> /// Gets or sets the current weather. /// </summary> public string CurrentWeather { get; set; } /// <summary> /// Gets or sets the low temperature for the day. /// </summary> public string DayLow { get; set; } /// <summary> /// Gets or sets the high temperature for the day. /// </summary> public string DayHigh { get; set; } } } }
La definizione della funzione include un metodo predefinito
Run
che è possibile usare per iniziare. Questo metodo di esempioRun
illustra alcune delle funzionalità disponibili con la funzionalità di funzioni personalizzate, ad esempio il passaggio di input e output diversi, inclusi i tipi .NET complessi.Il file <function-name>.cs include anche l'interfaccia
ILogger
, che fornisce il supporto per la registrazione degli eventi in una risorsa di Application Insights. È possibile inviare informazioni di tracciamento ad Application Insights e archiviare tali informazioni insieme a quelle dei flussi di lavoro, ad esempio:private readonly ILogger<WeatherForecast> logger; public WeatherForecast(ILoggerFactory loggerFactory) { logger = loggerFactory.CreateLogger<WeatherForecast>(); } [FunctionName("WeatherForecast")] public Task<Weather> Run([WorkflowActionTrigger] int zipCode, string temperatureScale) { this.logger.LogInformation("Starting WeatherForecast with Zip Code: " + zipCode + " and Scale: " + temperatureScale); <...> }
Sostituire il codice della funzione di esempio con il proprio e modificare il metodo predefinito
Run
per gli scenari personalizzati. In alternativa, è possibile copiare la funzione, inclusa la dichiarazione[FunctionName("<*function-name*>")]
, e quindi rinominare la funzione con un nome univoco. È quindi possibile modificare la funzione rinominata per soddisfare le proprie esigenze.
Questo esempio continua con il codice di esempio senza alcuna modifica.
Creare e compilare il codice
Dopo aver completato la scrittura del codice, compilare per assicurarsi che non esistano errori di compilazione. Il progetto di funzioni .NET include automaticamente le attività di compilazione, che compilano e quindi aggiungono il codice alla cartella llib\custom nel progetto dell'app per la logica in cui i flussi di lavoro cercano funzioni personalizzate da eseguire. Queste attività inseriscono gli assembly nella cartella lib\custom\net472 o lib\custom\net8, in base alla versione di .NET.
In Visual Studio Code, dal menu Terminale, selezionare Nuovo terminale.
Nell'elenco di directory di lavoro visualizzato, selezionare Funzioni come directory di lavoro corrente per il nuovo terminale.
Visual Studio Code apre una finestra del terminale con un prompt dei comandi.
Nella finestra Terminale, immettere dotnet restore al prompt dei comandi.
Visual Studio Code analizza i progetti e determina se sono aggiornati.
Dopo che il prompt dei comandi viene visualizzato nuovamente, immettere dotnet build. In alternativa, scegliere Esegui attività dal menu Terminale. Nell'elenco delle attività, selezionare Compila (Funzioni).
Se la compilazione ha esito positivo, nella finestra Terminale viene segnalato che la compilazione è riuscita.
Verificare che nel progetto dell'app per la logica siano presenti gli elementi seguenti:
Nell'area di lavoro, espandere le cartelle seguenti: LogicApp>lib\custom>net472 o net8, in base alla versione di .NET. Verificare che la sottocartella denominata net472 o net8 contenga rispettivamente i file assembly (DLL) necessari per eseguire il codice, incluso un file denominato <function-name>.dll.
Nell'area di lavoro espandere le cartelle seguenti: LogicApp>lib\custom><function-name>. Verificare che la sottocartella denominata <function-name> contenga un file function.json, che include i metadati relativi al codice della funzione scritto. La finestra di progettazione del flusso di lavoro usa questo file per determinare gli input e gli output necessari quando si chiama il codice.
L'esempio seguente mostra gli assembly di esempio generati e altri file nel progetto dell'app per la logica:
Chiamare il codice da un flusso di lavoro
Dopo aver verificato che il codice venga compilato e che il progetto dell'app per la logica contenga i file necessari per l'esecuzione del codice, aprire il flusso di lavoro predefinito incluso nel progetto dell'app per la logica.
Nell'area di lavoro, in LogicApp, espandere il nodo <workflow-name>, aprire il menu di scelta rapida per workflow.json e selezionare Apri finestra di progettazione.
Nella finestra di progettazione del flusso di lavoro che si apre, il flusso di lavoro predefinito, incluso nel progetto di app per la logica, viene visualizzato con il trigger e le azioni seguenti:
- Trigger predefinito di richiesta denominato Quando viene ricevuta una richiesta HTTP
- Azione predefinita denominata Chiamare una funzione locale in questa app per la logica
- Azione di risposta predefinita denominata Risposta, che viene usata per rispondere al chiamante solo quando si usa il trigger Richiesta
Selezionare l'azione denominata Chiama una funzione locale in questa app per la logica.
Il riquadro delle informazioni dell'azione si apre a destra.
Verificare e controllare che il valore del parametro Nome funzione sia impostato sulla funzione da eseguire. Esaminare o modificare qualsiasi altro valore di parametro usato dalla funzione.
Eseguire il debug del codice e del flusso di lavoro
Ripetere i passaggi seguenti per avviare l'emulatore di archiviazione Azurite tre volte: una volta per ogni servizi di Archiviazione di Azure seguente:
- Servizio Blob di Azure
- Servizio di accodamento di Azure
- Servizio tabelle di Azure
Dal menu Visualizza di Visual Studio Code, selezionare Riquadro comandi.
Nel prompt visualizzato, trovare e selezionare Azurite: Avvia servizio BLOB.
Nell'elenco di directory di lavoro visualizzato, selezionare LogicApp.
Ripetere questi passaggi per Azurite: Avvia Servizio di accodamento e Azurite: Avvia Servizio tabelle.
Il processo ha funzionato quando la barra delle applicazioni di Visual Studio Code, nella parte inferiore della schermata, mostra i tre servizi di archiviazione in esecuzione, ad esempio:
Collegare il debugger al progetto dell'app per la logica seguendo questa procedura:
Nella barra delle attività di Visual Studio Code, selezionare Avvia ed esegui debug. (Tastiera: CTRL+MAIUSC+D)
Nell'elenco Avvia ed esegui debug, selezionare Collega all'app per la logica (LogicApp), se non è già selezionata, e quindi selezionare Riproduci (freccia verde).
Viene visualizzata la finestra Terminale e viene visualizzato il processo di debug avviato. Viene quindi visualizzata la finestra Console di debug che mostra gli stati di debug. Nella parte inferiore di Visual Studio Code, la barra delle applicazioni diventa arancione, a indicare che il debugger .NET è caricato.
Collegare il debugger al progetto di funzioni .NET seguendo questa procedura, in base al codice:
Progetti ASP.NET 8
Dal menu Visualizza di Visual Studio Code, selezionare Riquadro comandi.
Nel riquadro comandi, trovare e selezionare Debug: Collega a un processo .NET 5+ o .NET Core.
Nell'elenco, trovare e selezionare il processo di dotnet.exe. Se esistono più processi dotnet.exe, selezionare il processo con il percorso seguente:
<drive-name>:\Users<user-name>.azure-functions-core-tools\Functions\ExtensionBundles\Microsoft.Azure.Functions.ExtensionBundle.Workflows<extension-bundle-version>\CustomCodeNetFxWorker\net8\Microsoft.Azure.Workflows.Functions.CustomCodeNetFxWorker.dll
Progetti .NET Framework
Nell'elenco Avvia ed esegui debug, selezionare Collega a funzioni .NET (Funzioni), se non è già selezionato, e quindi selezionare Riproduci (freccia verde).
Per impostare eventuali punti di interruzione, nella definizione della funzione (<function-name>.cs) o nella definizione del flusso di lavoro (workflow.json), individuare il numero di riga in cui si desidera il punto di interruzione e selezionare la colonna a sinistra, ad esempio:
Per eseguire manualmente il trigger Richiesta nel flusso di lavoro, aprire la pagina Panoramica del flusso di lavoro.
Dal progetto dell'app per la logica, aprire il menu di scelta rapida del file di workflow.json e selezionare Panoramica.
Nella pagina Panoramica del flusso di lavoro, il pulsante Esegui trigger è disponibile per quando si vuole avviare manualmente il flusso di lavoro. In Proprietà flusso di lavoro, il valore dell'URL di callback è l'URL di un endpoint chiamabile creato dal trigger Richiesta nel flusso di lavoro. È possibile inviare richieste a questo URL per attivare il flusso di lavoro da altre app, inclusi altri flussi di lavoro dell'app per la logica.
Nella barra degli strumenti della pagina Panoramica, selezionare Esegui trigger.
Dopo l'avvio dell'esecuzione del flusso di lavoro, il debugger attiva il primo punto di interruzione.
Nel menu Esegui o nella barra degli strumenti del debugger, selezionare un' azione di debug.
Al termine dell'esecuzione del flusso di lavoro, la pagina Panoramica mostra l'esecuzione completata e i dettagli di base sull'esecuzione.
Per esaminare altre informazioni sull'esecuzione del flusso di lavoro, selezionare l'esecuzione completata. In alternativa, nell'elenco accanto alla colonna Durata, selezionare Mostra esecuzione.
Distribuire il codice
È possibile distribuire le funzioni personalizzate nello stesso modo in cui si distribuisce il progetto di app per la logica. Indipendentemente dal fatto che si distribuisca da Visual Studio Code o si usi un processo DevOps CI/CD, assicurarsi di compilare il codice e che tutti gli assembly dipendenti esistano nella cartella di progetto dell'app per la logica seguente prima della distribuzione:
.NET 4.7.2: cartella lib/custom/net472
.NET 8: cartella lib/custom/net8
Per altre informazioni, vedere Distribuire flussi di lavoro Standard da Visual Studio Code ad Azure.
Risoluzione dei problemi
Errore del riquadro informazioni azione
Nella finestra di progettazione del flusso di lavoro, quando si seleziona l'azione predefinita denominata Chiamare una funzione locale in questa app per la logica, il riquadro delle informazioni dell'azione mostra il messaggio seguente:
Failed to retrieve dynamic inputs. Error details:
In questo scenario, esaminare il progetto di app per la logica per verificare se la cartella LogicApp\lib\custom è vuota. Se vuota, dal menu Terminale, selezionare Esegui attività>compila Funzioni.
Attualmente non sono in esecuzione processi con il nome specificato
Se viene visualizzato questo messaggio di errore quando si esegue il flusso di lavoro, è probabile che il processo del debugger sia collegato a Funzioni .NET, anziché all'app per la logica.
Per risolvere il problema, dall'elenco Avvia ed esegui debug, selezionare Collega all'app per la logica (LogicApp) e quindi selezionare Riproduci (triangolo verde).
Pacchetto non importato correttamente
Se nella finestra Output viene visualizzato un errore simile al messaggio seguente, assicurarsi di avere installato almeno la versione .NET 6.0. Se questa versione è installata, provare a disinstallare e reinstallare.
C:\Users\yourUserName\.nuget\packages\microsoft.net.sdk.functions\4.2.0\build\Microsoft.NET.Sdk.Functions.targets(83,5): warning : The ExtensionsMetadataGenerator package was not imported correctly. Are you missing 'C:\Users\yourUserName\.nuget\packages\microsoft.azure.webjobs.script.extensionsmetadatagenerator\4.0.1\build\Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator.targets' or 'C:\Users\yourUserName\.nuget\packages\microsoft.azure.webjobs.script.extensionsmetadatagenerator\4.0.1\build\Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator.props'? [C:\Desktop\...\custom-code-project\MyLogicAppWorkspace\Function\WeatherForecast.csproj] WeatherForecast -> C:\Desktop\...\custom-code-project\MyLogicAppWorkspace\Function\\bin\Debug\net472\WeatherForecast.dll C:\Users\yourUserName\.nuget\packages\microsoft.net.sdk.functions\4.2.0\build\Microsoft.NET.Sdk.Functions.Build.targets(32,5): error : It was not possible to find any compatible framework version [C:\Desktop\...\custom-code-project\MyLogicAppWorkspace\Function\WeatherForecast.csproj] C:\Users\yourUserName\.nuget\packages\microsoft.net.sdk.functions\4.2.0\build\Microsoft.NET.Sdk.Functions.Build.targets(32,5): error : The specified framework 'Microsoft.NETCore.App', version '6.0.0' was not found. [C:\Desktop\...\custom-code-project\MyLogicAppWorkspace\Function\WeatherForecast.csproj] C:\Users\yourUserName\.nuget\packages\microsoft.net.sdk.functions\4.2.0\build\Microsoft.NET.Sdk.Functions.Build.targets(32,5): error : - Check application dependencies and target a framework version installed at: [C:\Desktop\...\custom-code-project\MyLogicAppWorkspace\Function\WeatherForecast.csproj]
Errori di compilazione
Se la funzione non include variabili e si compila il codice, la finestra Output potrebbe mostrare i messaggi di errore seguenti:
C:\Users\yourUserName\...\custom-code-project\Function\func.cs (24,64): error CS1031: Type expected [C:\Users\yourUserName\...\custom-code-project\Function\func.csproj]
C:\Users\yourUserName\...\custom-code-project\Function\func.cs (24,64): error CS1001: Identifier expected [C:\Users\yourUserName\...\custom-code-project\Function\func.csproj]
Build FAILED.
C:\Users\yourUserName\...\custom-code-project\Function\func.cs (24,64): error CS1031: Type expected [C:\Users\yourUserName\...\custom-code-project\Function\func.csproj]
C:\Users\yourUserName\...\custom-code-project\Function\func.cs (24,64): error CS1001: Identifier expected [C:\Users\yourUserName\...\custom-code-project\Function\func.csproj]
0 Warning(s)
2 Error(s)
Per risolvere questo problema, nel metodo Run
del codice, aggiungere il parametro seguente:
string parameter1 = null
L'esempio seguente mostra come viene visualizzata la firma del metodo Run
:
public static Task<Weather> Run([WorkflowActionTrigger] int zipCode, string temperatureScale, string parameter1 = null)