Sviluppare Funzioni di Azure con Visual Studio

Visual Studio consente di sviluppare, testare e distribuire funzioni della libreria di classi C# in Azure. Se questa esperienza è la prima con Funzioni di Azure, vedere Introduzione a Funzioni di Azure.

Per iniziare subito, è consigliabile completare l'Avvio rapido di Funzioni per Visual Studio.

Questo articolo fornisce informazioni dettagliate su come usare Visual Studio per sviluppare funzioni della libreria di classi C# e pubblicarle in Azure. Esistono due modelli per lo sviluppo di funzioni della libreria di classi C#: il modello di lavoro isolato e il modello in-process.

Si sta leggendo la versione del modello di lavoro isolato in questo articolo. È possibile scegliere il modello preferito nella parte superiore dell'articolo.

Si sta leggendo la versione del modello in-process in questo articolo. È possibile scegliere il modello preferito nella parte superiore dell'articolo.

Se non diversamente specificato, le procedure e gli esempi mostrati sono per Visual Studio 2022. Per altre informazioni sulle versioni di Visual Studio 2022, vedere le note sulla versione o le note sulla versione di anteprima.

Prerequisiti

  • Visual Studio 2022, incluso il carico di lavoro sviluppo di Azure.

  • Altre risorse necessarie, ad esempio un account di archiviazione di Azure, vengono create nella sottoscrizione durante il processo di pubblicazione.

  • Se non si ha una sottoscrizione di Azure, creare un account Azure gratuito prima di iniziare.

Creare un progetto di Funzioni di Azure

Il modello di progetto Funzioni di Azure in Visual Studio crea un progetto di libreria di classi C# che è possibile pubblicare in un'app per le funzioni in Azure. È possibile usare un'app per le funzioni per raggruppare le funzioni in un'unità logica e semplificare la gestione, la distribuzione, il ridimensionamento e la condivisione delle risorse.

  1. Nel menu di Visual Studio selezionare File>Nuovo>Progetto.

  2. In Crea un nuovo progetto immettere funzioni nella casella di ricerca, scegliere il modello Funzioni di Azure e quindi selezionare Avanti.

  3. In Configura il nuovo progetto immettere un nome per il progetto e quindi selezionare Crea. Il nome dell'app per le funzioni deve essere valido come spazio dei nomi C#, quindi non usare caratteri di sottolineatura, trattini o altri caratteri non alfanumerici.

  4. Per le impostazioni di Crea una nuova applicazione Funzioni di Azure usare i valori della tabella seguente:

    Impostazione valore Descrizione
    Versione .NET .NET 6 Isolato Questo valore crea un progetto di funzione eseguito in un processo di lavoro Isolato. Il processo di lavoro Isolato supporta altre versioni non LTS di .NET e anche .NET Framework. Per altre informazioni, vedere Panoramica delle versioni del runtime per Funzioni di Azure.
    Modello di funzione Trigger HTTP Con questo valore viene creata una funzione attivata da una richiesta HTTP.
    Account di archiviazione (AzureWebJobsStorage) Emulatore di archiviazione Poiché un’app per le funzioni in Azure richiede un account di archiviazione, ne viene assegnato o creato uno quando si pubblica il progetto in Azure. Un trigger HTTP non usa una stringa di connessione dell'account di archiviazione di Azure. Tutti gli altri tipi di trigger richiedono una stringa di connessione dell'account di archiviazione di Azure valida.
    Livello di autorizzazione Anonimo Viene creata una funzione che può essere attivata da qualsiasi client senza dover fornire una chiave. Questa impostazione di autorizzazione consente di testare più facilmente la nuova funzione. Per maggiori informazioni, vedere Livello di autorizzazione.

    Screenshot delle impostazioni del progetto di Funzioni di Azure

    Impostazione valore Descrizione
    Versione .NET .NET 6 Questo valore crea un progetto di funzione che viene eseguito in-process con la versione 4.x del runtime di Funzioni di Azure. Per altre informazioni, vedere Panoramica delle versioni del runtime per Funzioni di Azure.
    Modello di funzione Trigger HTTP Con questo valore viene creata una funzione attivata da una richiesta HTTP.
    Account di archiviazione (AzureWebJobsStorage) Emulatore di archiviazione Poiché un’app per le funzioni in Azure richiede un account di archiviazione, ne viene assegnato o creato uno quando si pubblica il progetto in Azure. Un trigger HTTP non usa una stringa di connessione dell'account di archiviazione di Azure. Tutti gli altri tipi di trigger richiedono una stringa di connessione dell'account di archiviazione di Azure valida.
    Livello di autorizzazione Anonimo Viene creata una funzione che può essere attivata da qualsiasi client senza dover fornire una chiave. Questa impostazione di autorizzazione consente di testare più facilmente la nuova funzione. Per maggiori informazioni, vedere Livello di autorizzazione.

    Screenshot delle impostazioni del progetto di Funzioni di Azure

    Assicurarsi di impostare Livello di autorizzazione su Anonimo. Se si sceglie il livello predefinito Funzione, è necessario fornire la chiave di funzione nelle richieste di accesso all'endpoint della funzione.

  5. Selezionare Crea per creare il progetto di funzione e la funzione attivata da HTTP.

Dopo aver creato un progetto di Funzioni di Azure, il modello di progetto crea un progetto C#, installa i pacchetti NuGet Microsoft.Azure.Functions.Worker e Microsoft.Azure.Functions.Worker.Sdk, e imposta il framework di destinazione.

Dopo aver creato un progetto di Funzioni di Azure, il modello di progetto crea un progetto C#, installa il pacchetto NuGet Microsoft.NET.Sdk.Functions e imposta il framework di destinazione.

Il nuovo progetto contiene i file seguenti:

  • host.json: consente di configurare l'host di Funzioni. Queste impostazioni si applicano sia durante l'esecuzione in locale che nell'esecuzione in Azure. Per altre informazioni, vedere il riferimento su host.json.

  • local.settings.json: mantiene le impostazioni usate quando si esegue Funzioni localmente. Queste impostazioni non vengono usate durante l'esecuzione in Azure. Per maggiori informazioni, vedere File di impostazioni locali.

    Importante

    Poiché il file local.settings.json può contenere segreti, è necessario escluderlo dal controllo del codice sorgente del progetto. Assicurarsi che l'impostazione Copia nella directory di output per questo file sia impostata su Copia se più recente.

Per altre informazioni, vedere Struttura del progetto nella guida del ruolo di lavoro isolato.

Per altre informazioni, vedere Progetto di libreria di classi per Funzioni.

Usare le impostazioni dell'app in locale

Quando si esegue in un'app per le funzioni in Azure, le impostazioni richieste dalle funzioni vengono archiviate in modo sicuro nelle impostazioni dell'app. Durante lo sviluppo locale, queste impostazioni vengono invece aggiunte alla raccolta Values nel file local.settings.json. Il file local.settings.json archivia anche le impostazioni usate dagli strumenti di sviluppo locali.

Gli elementi nella raccolta di Values nel file di local.settings.json del progetto sono destinati a eseguire il mirroring degli elementi nelle impostazioni di applicazione dell'app per le funzioni in Azure.

Visual Studio non carica automaticamente le impostazioni in local.settings.json quando si pubblica il progetto. Per assicurarsi che queste impostazioni esistano anche nell'app per le funzioni in Azure, caricarle dopo la pubblicazione del progetto. Per altre informazioni, vedere Impostazioni dell'app per le funzioni. I valori di una raccolta ConnectionStrings non vengono mai pubblicati.

Il codice può anche leggere i valori delle impostazioni dell'app per le funzioni come variabili di ambiente. Per altre informazioni, vedere Variabili di ambiente.

Configurare il progetto per lo sviluppo locale

Il runtime di Funzioni usa un account di archiviazione di Azure internamente. Per tutti i tipi di trigger diversi da HTTP e webhook, impostare la chiave Values.AzureWebJobsStorage su una stringa di connessione valida dell'account di archiviazione di Azure. L'app per le funzioni può anche usare l'emulatore Azurite per l'impostazione di connessione AzureWebJobsStorage richiesta dal progetto. Per usare l'emulatore, impostare il valore di AzureWebJobsStorage su UseDevelopmentStorage=true. Modificare questa impostazione impostando una stringa di connessione effettiva dell'account di archiviazione prima della distribuzione. Per altre informazioni, vedere Emulatore di archiviazione locale.

Per impostare la stringa di connessione dell'account di archiviazione:

  1. Nel portale di Azure passare all'account di archiviazione.

  2. Nella scheda Chiavi di accesso, sotto Sicurezza e rete, copiare la stringa di connessione di key1.

  3. Nel progetto aprire il file local.settings.json e impostare il valore della chiave AzureWebJobsStorage sulla stringa di connessione copiata.

  4. Ripetere il passaggio precedente per aggiungere chiavi univoche alla matrice di Values per tutte le altre connessioni richieste dalle funzioni.

Aggiungere una funzione al progetto

Nelle funzioni della libreria di classi C# le associazioni usate dalla funzione vengono definite applicando attributi nel codice. Quando si creano i trigger di funzione dai modelli forniti, vengono applicati automaticamente gli attributi del trigger.

  1. In Esplora soluzioni, fare clic con il pulsante destro del mouse sul nodo del progetto e selezionare Aggiungi>Nuova funzione di Azure.

  2. Immettere un nome per la classe e quindi selezionare Aggiungi.

  3. Scegliere il trigger, impostare le proprietà di associazione necessarie e quindi selezionare Aggiungi. L'esempio seguente mostra le impostazioni per creare una funzione attivata da un'archiviazione code.

    Creare una funzione trigger di archiviazione code

    Per un trigger del servizio di archiviazione di Azure, selezionare la casella Configurare la connessione e viene richiesto di scegliere tra l'uso di un emulatore di archiviazione Azurite o il riferimento a un account di archiviazione di Azure di cui è stato effettuato il provisioning. Selezionare Avanti e, se si sceglie un account di archiviazione, Visual Studio tenta di connettersi all'account Azure e ottenere la stringa di connessione. Scegliere Salva valore della stringa di connessione nel file dei segreti utente locali e quindi Fine per creare la classe trigger.

    Questo esempio di trigger usa un'impostazione dell'applicazione per la connessione di archiviazione con una chiave denominata QueueStorage. Questa chiave, archiviata nel file local.settings.json, fa riferimento all'emulatore Azurite o a un account di archiviazione di Azure.

  4. Si esamini la classe appena aggiunta. La classe C# seguente rappresenta ad esempio una funzione trigger di archiviazione code di base:

    Viene visualizzato un metodo Run() statico attribuito con Function. Questo attributo indica che il metodo è il punto di ingresso per la funzione.

    using System;
    using Azure.Storage.Queues.Models;
    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Extensions.Logging;
    
    namespace Company.Function
    {
        public class QueueTriggerCSharp
        {
            private readonly ILogger<QueueTriggerCSharp> _logger;
    
            public QueueTriggerCSharp(ILogger<QueueTriggerCSharp> logger)
            {
                _logger = logger;
            }
    
            [Function(nameof(QueueTriggerCSharp))]
            public void Run([QueueTrigger("PathValue", Connection = "ConnectionValue")] QueueMessage message)
            {
                _logger.LogInformation($"C# Queue trigger function processed: {message.MessageText}");
            }
        }
    }
    

    Viene visualizzato un metodo Run() statico attribuito con FunctionName. Questo attributo indica che il metodo è il punto di ingresso per la funzione.

    using System;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Host;
    using Microsoft.Extensions.Logging;
    
    namespace Company.Function
    {
        public class QueueTriggerCSharp
        {
            [FunctionName("QueueTriggerCSharp")]
            public void Run([QueueTrigger("PathValue", Connection = "ConnectionValue")]string myQueueItem, ILogger log)
            {
                log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
            }
        }
    }
    

Un attributo specifico dell'associazione viene applicato a ogni parametro di associazione fornito al metodo del punto di ingresso. L'attributo accetta le informazioni di associazione come parametri. Nell'esempio precedente il primo parametro ha un attributo QueueTrigger applicato, che indica una funzione trigger di archiviazione code. Il nome della coda e il nome di impostazione della stringa di connessione vengono passati come parametri all'attributo QueueTrigger. Per altre informazioni, vedere Associazioni di archiviazione code in Funzioni di Azure.

Usare la procedura descritta in precedenza per aggiungere altre funzioni al progetto di app per le funzioni. Ogni funzione nel progetto può avere un trigger diverso, ma una funzione deve avere esattamente un trigger. Per altre informazioni, vedere Concetti relativi a trigger e associazioni in Funzioni di Azure.

Aggiungere associazioni

Come nel caso dei trigger, le associazioni di input e output vengono aggiunte alla funzione come attributi di associazione. Per aggiungere associazioni a una funzione, procedere come segue:

  1. Assicurarsi di configurare il progetto per lo sviluppo locale.

  2. Aggiungere il pacchetto di estensione NuGet appropriato per l'associazione specifica individuando i requisiti del pacchetto NuGet specifici dell'associazione nell'articolo di riferimento per l'associazione. I requisiti del pacchetto per il trigger di Hub eventi sono ad esempio disponibili nell'articolo di riferimento sulle associazioni di Hub eventi.

  3. Usare il comando seguente nella console di Gestione pacchetti per installare un pacchetto specifico:

    Install-Package Microsoft.Azure.Functions.Worker.Extensions.<BINDING_TYPE> -Version <TARGET_VERSION>
    
    Install-Package Microsoft.Azure.WebJobs.Extensions.<BINDING_TYPE> -Version <TARGET_VERSION>
    

    In questo esempio sostituire <BINDING_TYPE> con il nome specifico dell'estensione di associazione e <TARGET_VERSION> con una versione specifica del pacchetto, ad esempio 4.0.0. Le versioni valide sono elencate nelle pagine dei singoli pacchetti in NuGet.org.

  4. Se ci sono impostazioni dell'app richieste dall'associazione, aggiungerle alla raccolta Values nel file di impostazioni locali.

    La funzione usa questi valori quando viene eseguito in locale. Quando la funzione viene eseguita nell'app per le funzioni in Azure, usa le impostazioni dell'app per le funzioni. Visual Studio semplifica la pubblicazione delle impostazioni locali in Azure.

  5. Aggiungere l'attributo di associazione appropriato per la firma del metodo. Nell'esempio seguente un messaggio della coda attiva la funzione e l'associazione di output crea un nuovo messaggio della coda con lo stesso testo in una coda diversa.

     public class QueueTrigger
    {
        private readonly ILogger _logger;
    
        public QueueTrigger(ILoggerFactory loggerFactory)
        {
            _logger = loggerFactory.CreateLogger<QueueTrigger>();
        }
    
        [Function("CopyQueueMessage")]
        [QueueOutput("myqueue-items-destination", Connection = "QueueStorage")]
        public string Run([QueueTrigger("myqueue-items-source", Connection = "QueueStorage")] string myQueueItem)
        {
            _logger.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
            return myQueueItem;
        }
    }
    

    L'attributo QueueOutput definisce l'associazione nel metodo. Per più associazioni di output, è invece necessario posizionare questo attributo su una proprietà stringa dell'oggetto restituito. Per altre informazioni, vedere Più associazioni di output.

    public static class SimpleExampleWithOutput
    {
        [FunctionName("CopyQueueMessage")]
        public static void Run(
            [QueueTrigger("myqueue-items-source", Connection = "QueueStorage")] string myQueueItem, 
            [Queue("myqueue-items-destination", Connection = "QueueStorage")] out string myQueueItemCopy,
            ILogger log)
        {
            log.LogInformation($"CopyQueueMessage function processed: {myQueueItem}");
            myQueueItemCopy = myQueueItem;
        }
    }
    

    L'attributo Queue nel parametro out definisce l'associazione di output.

    La connessione all'archiviazione code viene ottenuta dall'impostazione QueueStorage. Per altre informazioni, vedere l'articolo di riferimento per l'associazione specifica.

Per un elenco completo delle associazioni supportate da Funzioni, vedere Associazioni supportate.

Eseguire funzioni localmente

Azure Functions Core Tools consente di eseguire il progetto Funzioni di Azure nel computer di sviluppo locale. Quando si preme F5 per eseguire il debug di un progetto di Funzioni, l'host funzioni locale (func.exe) inizia ad ascoltare su una porta locale (in genere 7071). Tutti gli endpoint di funzione chiamabili vengono scritti nell'output ed è possibile usare questi endpoint per testare le funzioni. Per altre informazioni, vedere Usare Azure Functions Core Tools. Viene richiesto di installare questi strumenti al primo avvio di una funzione da Visual Studio.

Per avviare la funzione in Visual Studio in modalità di debug:

  1. Premere F5. Se viene visualizzata, accettare la richiesta di Visual Studio di scaricare e installare gli strumenti dell'interfaccia della riga di comando Azure Functions Core Tools. Potrebbe essere necessario anche abilitare un'eccezione del firewall per consentire agli strumenti di gestire le richieste HTTP.

  2. Con il progetto in esecuzione, testare il codice come si fa con una funzione distribuita.

    Quando si esegue Visual Studio in modalità di debug, i punti di interruzione vengono raggiunti come previsto.

Per uno scenario di test più dettagliato con Visual Studio, vedere Test delle funzioni.

Pubblicare in Azure

Quando si pubblica il progetto di funzioni in Azure, Visual Studio usa distribuzione ZIP per distribuire i file di progetto. Quando possibile, è consigliabile selezionare anche Esegui da pacchetto in modo che il progetto venga eseguito nel pacchetto di distribuzione (.zip). Per altre informazioni, vedere Eseguire le funzioni da un file di pacchetto in Azure.

Non eseguire la distribuzione in Funzioni di Azure usando Distribuzione Web (msdeploy).

Usare la procedura seguente per pubblicare il progetto in un'app per le funzioni in Azure.

  1. In Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto e scegliere Pubblica. In Destinazione, selezionare Azure e quindi avanti.

    Screenshot del riquadro di pubblicazione.

  2. In Destinazione specifica selezionare App per le funzioni di Azure (Windows). Viene creata un'app per le funzioni eseguita in Windows. Selezionare Avanti.

    Screenshot del riquadro di pubblicazione con una destinazione specifica.

  3. Nella pagina Istanza di Funzioni selezionare Crea una nuova istanza di Funzioni di Azure.

    Screenshot che mostra l'opzione Crea una nuova istanza dell'app per le funzioni.

  4. Creare una nuova istanza usando i valori specificati nella tabella seguente:

    Impostazione valore Descrizione
    Nome Nome globalmente univoco Nome che identifica in modo univoco la nuova app per le funzioni. Accettare questo nome o immetterne uno nuovo. I caratteri validi sono a-z, 0-9 e -.
    Abbonamento Sottoscrizione in uso Sottoscrizione di Azure da usare. Accettare questa sottoscrizione o selezionarne un'altra dall'elenco a discesa.
    Gruppo di risorse Nome del gruppo di risorse Gruppo di risorse in cui si desidera creare l'app per le funzioni. Per creare un nuovo gruppo di risorse, selezionare Nuovo. È anche possibile scegliere un gruppo di risorse esistente dall'elenco a discesa.
    Tipo di piano Consumo Quando si pubblica il progetto in un'app per le funzioni eseguita in un piano a consumo, vengono addebitati solo i costi relativi alle esecuzioni dell'app per le funzioni. Altri piani di hosting comportano costi più elevati.
    Location La località del piano di servizio app Scegliere una località in un'area di Azure nelle vicinanze o vicino ad altri servizi a cui accedono le funzioni.
    Archiviazione di Azure Account di archiviazione per utilizzo generico L'account di archiviazione di Azure è necessario per il runtime di Funzioni. Selezionare Nuovo per configurare un account di archiviazione per utilizzo generico. Si può anche scegliere di usare un account esistente che soddisfi i requisiti dell'account di archiviazione.
    Application Insights Istanza di Application Insights È consigliabile abilitare l'integrazione di Azure Application Insights per l'app per le funzioni. Selezionare Nuovo per creare una nuova istanza, in un'area di lavoro Log Analytics nuova o esistente. È anche possibile scegliere un'istanza esistente.

    Screenshot della finestra di dialogo Crea servizio app.

  5. Selezionare Crea per creare un'app per le funzioni e le relative risorse in Azure. Lo stato di creazione della risorsa viene visualizzato nell'angolo in basso a sinistra della finestra.

  6. In Istanza di funzioni assicurarsi che sia selezionata l'opzione Esegui da file di pacchetto. L'app per le funzioni viene distribuita usando la distribuzione ZIP con la modalità esecuzione da pacchetto abilitata. La distribuzione ZIP è il metodo di distribuzione consigliato per il progetto di funzioni, perché offre prestazioni più elevate.

    Screenshot del riquadro di completamento della creazione del profilo.

  7. Selezionare Fine e quindi, nella pagina Pubblica, selezionare Pubblica per distribuire il pacchetto contenente i file di progetto nella nuova app per le funzioni in Azure.

    Al termine della distribuzione, l'URL radice dell'app per le funzioni in Azure viene visualizzato nella scheda Pubblica.

  8. Nella sezione Hosting della scheda Pubblica selezionare Apri nel portale di Azure. La nuova risorsa di Azure dell'app per le funzioni viene aperta nel portale di Azure.

    Screenshot del messaggio di operazione riuscita di pubblicazione.

Impostazioni dell'app per le funzioni

Visual Studio non carica automaticamente queste impostazioni quando si pubblica il progetto. Tutte le impostazioni aggiunte al local.settings.json devono essere aggiunte anche all'app funzione in Azure.

Il modo più semplice per caricare le impostazioni necessarie nell'app per le funzioni in Azure consiste nell'espandere i tre puntini accanto alla sezione Hosting e selezionare il collegamento Gestisci impostazioni del servizio app di Azure visualizzato dopo la pubblicazione del progetto.

Impostazioni nella finestra Pubblica

Selezionando questo collegamento viene visualizzata la finestra di dialogo impostazioni applicazione per l'app per le funzioni, in cui è possibile aggiungere nuove impostazioni dell'applicazione o modificarne quelle esistenti.

Impostazioni delle applicazioni

Locale visualizza un valore di impostazione nel file local.settings.json e Remoto visualizza un valore di impostazione corrente nell'app per le funzioni in Azure. Scegliere Aggiungi impostazione per creare una nuova impostazione dell'app. Usare il collegamento Inserisci valore da locale per copiare un valore di impostazione nel campo Remoto. Le modifiche in sospeso vengono scritte nel file delle impostazioni locali e nell'app per le funzioni quando si seleziona OK.

Nota

Per impostazione predefinita, il file local.settings.json non viene archiviato nel controllo del codice sorgente. Ciò significa che se si clona un progetto di Funzioni locale dal controllo del codice sorgente, il progetto non ha un file local.settings.json. In questo caso, è necessario creare manualmente il file local.settings.json nella radice del progetto in modo che la finestra di dialogo Impostazioni applicazione funzioni come previsto.

È anche possibile gestire le impostazioni dell'applicazione in uno degli altri modi seguenti:

Debug remoto

Per eseguire il debug remoto dell'app per le funzioni, è necessario pubblicare una configurazione di debug del progetto. È anche necessario abilitare il debug remoto nell'app per le funzioni in Azure.

Questa sezione presuppone che l'app per le funzioni sia già stata pubblicata usando una configurazione di versione.

Considerazioni sul debug remoto

  • Il debug remoto non è consigliato in un servizio di produzione.
  • Se il debug Just My Code è abilitato, disabilitarlo.
  • Evitare interruzioni prolungate in corrispondenza dei punti di interruzione durante il debug remoto. In Azure i processi interrotti per più di alcuni minuti vengono considerati come processi che non rispondono e vengono arrestati.
  • Durante il debug, il server invia i dati a Visual Studio, con possibili implicazioni sui costi della larghezza di banda. Per informazioni sui costi della larghezza di banda, vedere Prezzi di Azure.
  • Il debug remoto viene disabilitato automaticamente nell'app per le funzioni dopo 48 ore. Dopo 48 ore, sarà necessario riabilitare il debug remoto.

Collegare il debugger

Il modo in cui si collega il debugger dipende dalla modalità di esecuzione. Quando si esegue il debug di un'app del processo di lavoro isolato, è attualmente necessario collegare il debugger remoto a un processo .NET separato e sono necessari diversi altri passaggi di configurazione.

Al termine, è consigliabile disabilitare il debug remoto.

Per collegare un debugger remoto a un'app per le funzioni in esecuzione in un processo separato dall'host di Funzioni:

  1. Nella scheda Pubblica selezionare i puntini di sospensione (...) nella sezione Hosting e quindi scegliere Scarica profilo di pubblicazione. Questa azione scarica una copia del profilo di pubblicazione e apre il percorso di download. È necessario questo file, che contiene le credenziali usate per il collegamento al processo di lavoro isolato in esecuzione in Azure.

    Attenzione

    Il file con estensione publishsettings contiene le credenziali (non codificate) usate per amministrare l'app per le funzioni. La procedura consigliata per la sicurezza per questo file consiste nell'archiviarla temporaneamente all'esterno delle directory di origine (ad esempio nella cartella Libraries\Documents) e quindi eliminarla dopo che non è più necessaria. Un utente malintenzionato che riesce ad accedere al file .publishsettings può modificare, creare ed eliminare l’app per le funzioni.

  2. Nella scheda Pubblica selezionare i puntini di sospensione (...) nella sezione Hosting e quindi scegliere Collega debugger.

    Screenshot del collegamento del debugger da Visual Studio.

    Visual Studio si connette all'app per le funzioni e abilita il debug remoto, se non è già abilitato.

    Nota

    Poiché il debugger remoto non è in grado di connettersi al processo host, è possibile che venga visualizzato un errore. In ogni caso, il debug predefinito non verrà suddiviso nel codice.

  3. Tornare in Visual Studio, copiare l'URL per il sito in Hosting nella pagina Pubblica.

  4. Dal menu Debug selezionare Connetti a processo e nella finestra Connetti a processo incollare l'URL nella destinazione di connessione, rimuovere https:// e aggiungere la porta :4024.

    Verificare che la destinazione sia simile a <FUNCTION_APP>.azurewebsites.net:4024 e premere INVIO.

    Finestra di dialogo di collegamento a Visual Studio

  5. Se richiesto, consentire l'accesso a Visual Studio tramite il firewall locale.

  6. Quando vengono richieste le credenziali, anziché le credenziali utente locali scegliere un account diverso (Altre opzioni in Windows). Specificare i valori di userName e userPWD dal profilo pubblicato per Indirizzo di posta elettronica e Password nella finestra di dialogo di autenticazione in Windows. Dopo aver stabilito una connessione sicura con il server di distribuzione, vengono visualizzati i processi disponibili.

    Immettere credenziali in Visual Studio

  7. Selezionare Mostra processo da tutti gli utenti e quindi scegliere dotnet.exe e selezionare Connetti. Al termine dell'operazione, si è collegati al codice della libreria di classi C# in esecuzione in un processo di lavoro isolato. A questo punto, è possibile eseguire il debug dell'app per le funzioni come di consueto.

Per collegare un debugger remoto a un'app per le funzioni in esecuzione in-process con l'host funzioni:

  • Nella scheda Pubblica selezionare i puntini di sospensione (...) nella sezione Hosting e quindi scegliere Collega debugger.

    Screenshot del collegamento del debugger da Visual Studio.

Visual Studio si connette all'app per le funzioni e abilita il debug remoto, se non è già abilitato. Individua e collega anche il debugger al processo host per l'app. A questo punto, è possibile eseguire il debug dell'app per le funzioni come di consueto.

Disabilitare il debug remoto

Dopo aver completato il debug remoto del codice, è necessario disabilitare il debug remoto nel portale di Azure. Il debug remoto viene disabilitato automaticamente dopo 48 ore, nel caso in cui si dimentica.

  1. Nella scheda Pubblica del progetto selezionare i puntini di sospensione (...) nella sezione Hosting e scegliere Apri nel portale di Azure. Questa azione apre l'app per le funzioni nel portale di Azure in cui viene distribuito il progetto.

  2. Nell'app per le funzioni selezionare Configurazione in Impostazioni, scegliere Impostazioni generali, impostare Debug remoto su Disattivato e selezionare Salva quindi Continua.

Dopo il riavvio dell'app per le funzioni, non è più possibile connettersi in remoto ai processi remoti. È possibile usare questa stessa scheda nel portale di Azure per abilitare il debug remoto all'esterno di Visual Studio.

Monitoraggio delle funzioni

È consigliabile monitorare l'esecuzione delle funzioni tramite l'integrazione dell'app per le funzioni con Azure Application Insights. È consigliabile abilitare questa integrazione quando si crea l'app per le funzioni durante la pubblicazione di Visual Studio.

Se per qualche motivo l'integrazione non è stata eseguita durante la pubblicazione, è comunque necessario abilitare l'integrazione di Application Insights per l'app per le funzioni in Azure.

Per altre informazioni sul monitoraggio con Application Insights, vedere Monitorare Funzioni di Azure.

Test delle funzioni

Questa sezione descrive come creare un progetto di modello in-process C# che è possibile testare con xUnit.

Test di Funzioni di Azure con C# in Visual Studio

1. Configurazione

Usare questi passaggi per configurare l'ambiente, incluso il progetto e le funzioni dell'app, necessari per supportare i test:

  1. Creare una nuova app funzioni e denominarla Funzioni
  2. Creare una funzione HTTP dal modello e denominarla MyHttpTrigger.
  3. Creare una funzione del timer dal modello e denominarla MyTimerTrigger.
  4. Creare un'app di test xUnit nella soluzione e denominarla Functions.Tests. Rimuovere i file di test predefiniti.
  5. Usare NuGet per aggiungere un riferimento dall'app di test a Microsoft.AspNetCore.Mvc
  6. Fare riferimento all'app Funzioni dall'app Functions.Tests.

Ora che vengono create i progetti, è possibile creare le classi usate per eseguire i test automatizzati.

2. Crea classi di test

Ogni funzione accetta un'istanza di ILogger per gestire la registrazione dei messaggi. Alcuni test non registrano messaggi oppure non hanno alcun problema per la modalità di implementazione della registrazione. Altri test devono valutare i messaggi registrati per determinare se si sta passando un test.

  1. Creare una classe denominata ListLogger, che contiene un elenco interno di messaggi da valutare durante il test. Per implementare l'interfaccia di ILogger richiesta, la classe richiede un ambito. La classe seguente simula un ambito per i test case da passare alla classe ListLogger.

  2. Creare una nuova classe nel progetto Functions.Tests denominato NullScope.cs e aggiungere questo codice:

    using System;
    
    namespace Functions.Tests
    {
        public class NullScope : IDisposable
        {
            public static NullScope Instance { get; } = new NullScope();
    
            private NullScope() { }
    
            public void Dispose() { }
        }
    }
    
  3. Creare una classe nel progetto Functions.Tests denominato ListLogger.cs e aggiungere questo codice:

    using Microsoft.Extensions.Logging;
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Functions.Tests
    {
        public class ListLogger : ILogger
        {
            public IList<string> Logs;
    
            public IDisposable BeginScope<TState>(TState state) => NullScope.Instance;
    
            public bool IsEnabled(LogLevel logLevel) => false;
    
            public ListLogger()
            {
                this.Logs = new List<string>();
            }
    
            public void Log<TState>(LogLevel logLevel,
                                    EventId eventId,
                                    TState state,
                                    Exception exception,
                                    Func<TState, Exception, string> formatter)
            {
                string message = formatter(state, exception);
                this.Logs.Add(message);
            }
        }
    }
    

    La classe ListLogger implementa i membri seguenti come contrattato dall'interfaccia ILogger:

    • BeginScope: gli ambiti aggiungono contesto alla registrazione. In questo caso, il test punta solo all'istanza statica nella classe NullScope per consentire la funzione del test.

    • IsEnabled: viene fornito un valore predefinito di false.

    • Log: Questo metodo usa la funzione fornita formatter per formattare il messaggio e quindi aggiunge il testo risultante nella raccolta Logs.

    La raccolta Logs è un'istanza di List<string> e viene inizializzata nel costruttore.

  4. Creare un file di codice nel progetto Functions.Tests denominato LoggerTypes.cs e aggiungere questo codice:

    namespace Functions.Tests
    {
        public enum LoggerTypes
        {
            Null,
            List
        }
    }
    

    Questa enumerazione specifica il tipo di logger usato dai test.

  5. Creare una classe nel progetto Functions.Tests denominata TestFactory.cs e aggiungere questo codice:

    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Http.Internal;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Logging.Abstractions;
    using Microsoft.Extensions.Primitives;
    using System.Collections.Generic;
    
    namespace Functions.Tests
    {
        public class TestFactory
        {
            public static IEnumerable<object[]> Data()
            {
                return new List<object[]>
                {
                    new object[] { "name", "Bill" },
                    new object[] { "name", "Paul" },
                    new object[] { "name", "Steve" }
    
                };
            }
    
            private static Dictionary<string, StringValues> CreateDictionary(string key, string value)
            {
                var qs = new Dictionary<string, StringValues>
                {
                    { key, value }
                };
                return qs;
            }
    
            public static HttpRequest CreateHttpRequest(string queryStringKey, string queryStringValue)
            {
                var context = new DefaultHttpContext();
                var request = context.Request;
                request.Query = new QueryCollection(CreateDictionary(queryStringKey, queryStringValue));
                return request;
            }
    
            public static ILogger CreateLogger(LoggerTypes type = LoggerTypes.Null)
            {
                ILogger logger;
    
                if (type == LoggerTypes.List)
                {
                    logger = new ListLogger();
                }
                else
                {
                    logger = NullLoggerFactory.Instance.CreateLogger("Null Logger");
                }
    
                return logger;
            }
        }
    }
    

    La classe TestFactory implementa i seguenti membri:

    • Data: questa proprietà restituisce una raccolta di dati di esempio IEnumerable. Le coppie chiave-valore rappresentano valori che vengono passati in una stringa di query.

    • CreateDictionary: questo metodo accetta una coppia chiave/valore come argomenti e restituisce un nuovo Dictionary usato per creare QueryCollection per rappresentare i valori della stringa di query.

    • CreateHttpRequest: questo metodo crea una richiesta HTTP inizializzata con i parametri della stringa di query specificati.

    • CreateLogger: in base al tipo di logger, questo metodo restituisce una classe logger usata per il test. ListLogger tiene traccia dei messaggi registrati disponibili per la valutazione nei test.

  6. Creare una classe nel progetto Functions.Tests denominata FunctionsTests.cs e aggiungere questo codice:

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Logging;
    using Xunit;
    
    namespace Functions.Tests
    {
        public class FunctionsTests
        {
            private readonly ILogger logger = TestFactory.CreateLogger();
    
            [Fact]
            public async void Http_trigger_should_return_known_string()
            {
                var request = TestFactory.CreateHttpRequest("name", "Bill");
                var response = (OkObjectResult)await MyHttpTrigger.Run(request, logger);
                Assert.Equal("Hello, Bill. This HTTP triggered function executed successfully.", response.Value);
            }
    
            [Theory]
            [MemberData(nameof(TestFactory.Data), MemberType = typeof(TestFactory))]
            public async void Http_trigger_should_return_known_string_from_member_data(string queryStringKey, string queryStringValue)
            {
                var request = TestFactory.CreateHttpRequest(queryStringKey, queryStringValue);
                var response = (OkObjectResult)await MyHttpTrigger.Run(request, logger);
                Assert.Equal($"Hello, {queryStringValue}. This HTTP triggered function executed successfully.", response.Value);
            }
    
            [Fact]
            public void Timer_should_log_message()
            {
                var logger = (ListLogger)TestFactory.CreateLogger(LoggerTypes.List);
                new MyTimerTrigger().Run(null, logger);
                var msg = logger.Logs[0];
                Assert.Contains("C# Timer trigger function executed at", msg);
            }
        }
    }
    

    I membri implementati in questa classe sono:

    • Http_trigger_should_return_known_string: questo test crea una richiesta con i valori della stringa di query di name=Bill a una funzione HTTP e verifica che venga restituita la risposta prevista.

    • Http_trigger_should_return_string_from_member_data: questo test usa attributi xUnit per fornire dati di esempio alla funzione HTTP.

    • Timer_should_log_message: questo test crea un'istanza di ListLogger e la passa a una funzione timer. Una volta eseguita la funzione, il log viene controllato per verificare che sia presente il messaggio previsto.

  7. Per accedere alle impostazioni dell'applicazione nei test, è possibile inserire un'istanza di IConfiguration con valori di variabile di ambiente fittizi nella funzione.

3. Esecuzione dei test

Per eseguire i test, passare a Esplora test e selezionare Esegui tutti i test in Visualizzazione.

Test di Funzioni di Azure con C# in Visual Studio

4. Esecuzione del debug dei test

Per eseguire il debug dei test, impostare un punto di interruzione in un test, passare a Explorer del Test e selezionare Esegui > Ultima esecuzione del Debug.

Passaggi successivi

Per altre informazioni sugli strumenti di base di Funzioni di Azure, vedere Usare Azure Functions Core Tools.