Guida di riferimento a Funzioni di Azure per sviluppatori di script C# (.csx)
Questo articolo riporta un'introduzione allo sviluppo di Funzioni di Azure tramite script C# (.csx).
Importante
Lo script C# è supportato principalmente per offrire un'esperienza pratica nel portale per iniziare rapidamente a creare ed eseguire funzioni C#. Per le app di qualità di produzione, è invece consigliabile sviluppare le funzioni C# in locale come progetto di libreria di classi C# compilato. Per informazioni su come eseguire la migrazione di un progetto script C# a un progetto di libreria di classi C# (ruolo di lavoro isolato), vedere Convertire un'app script C# in un progetto C#.
Funzioni di Azure consente di sviluppare funzioni usando C# in uno dei modi seguenti:
Type | Processo di esecuzione | Estensione del codice | Ambiente di sviluppo | Riferimento |
---|---|---|---|---|
Script C# | In-Process | .csx | Portale Strumenti di base |
Questo articolo |
Libreria di classi C# (ruolo di lavoro isolato) | Processo di lavoro isolato | .cs | Visual Studio Visual Studio Code Strumenti di base |
Funzioni del processo di lavoro isolato .NET |
Libreria di classi C# (In-Process) | In-Process | .cs | Visual Studio Visual Studio Code Strumenti di base |
Funzioni della libreria di classi C# In-Process |
Funzionamento di CSX
I dati vengono trasmessi alla funzione C# tramite argomenti del metodo. I nomi di argomento sono specificati in un file function.json
e sono disponibili nomi predefiniti per l'accesso a elementi quali il logger delle funzioni e i token di annullamento.
Il formato .csx consente di scrivere meno "boilerplate" e di concentrarsi solo sulla scrittura della funzione C#. Anziché eseguire il wrapping di tutti gli elementi in un spazio dei nomi e classe, definire semplicemente un metodo Run
. Includere tutti i riferimenti ad assembly e gli spazi dei nomi all'inizio del file come di consueto.
I file con estensione .csx di un'app per le funzioni vengono compilati quando viene inizializzata un'istanza. Questo passaggio di compilazione implica che operazioni quali l'avvio a freddo potrebbero richiedere più tempo per le funzioni script C# rispetto alle librerie di classi C#. Questo passaggio di compilazione è anche il motivo per cui le funzioni script C# sono modificabili nel portale di Azure, mentre le librerie di classi C# non lo sono.
Struttura delle cartelle
La struttura di cartelle per un progetto di script C# ha un aspetto simile al seguente esempio:
FunctionsProject
| - MyFirstFunction
| | - run.csx
| | - function.json
| | - function.proj
| - MySecondFunction
| | - run.csx
| | - function.json
| | - function.proj
| - host.json
| - extensions.csproj
| - bin
È presente un file host.json condiviso che può essere usato per configurare l'app per le funzioni. Ogni funzione ha il proprio file di codice (con estensione csx) e il file di configurazione delle associazioni (function.json).
Le estensioni di binding richieste nella versione 2.x e successive del runtime di Funzioni sono definite nel file extensions.csproj
, con gli effettivi file di libreria inclusi nella cartella bin
. Quando si sviluppa una funzione in locale, è necessario registrare le estensioni di associazione. Quando si sviluppano funzioni nel portale di Azure, la registrazione viene eseguita automaticamente.
Associazione agli argomenti
I dati di input o output sono associati a un parametro di una funzione script C# tramite la proprietà name
nel file di configurazione function.json. L'esempio seguente mostra un file function.json e un file run.csx per una funzione attivata dalla coda. Il parametro che riceve i dati dal messaggio della coda è denominato myQueueItem
perché questo è il valore della proprietà name
.
{
"disabled": false,
"bindings": [
{
"type": "queueTrigger",
"direction": "in",
"name": "myQueueItem",
"queueName": "myqueue-items",
"connection":"MyStorageConnectionAppSetting"
}
]
}
#r "Microsoft.WindowsAzure.Storage"
using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage.Queue;
using System;
public static void Run(CloudQueueMessage myQueueItem, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem.AsString}");
}
L'istruzione #r
è spiegata più avanti in questo articolo.
Tipi supportati per le associazioni
Ogni associazione supporta determinati tipi. Ad esempio è possibile usare un trigger di BLOB con un parametro stringa, un parametro POCO, un parametro CloudBlockBlob
o uno dei molti altri tipi supportati. L'articolo di riferimento sull'associazione relativo alle associazioni BLOB elenca tutti i tipi di parametri supportati per i trigger di BLOB. Per altre informazioni, vedere Trigger e associazioni e i documenti di riferimento per ogni tipo di associazione.
Suggerimento
Se si prevede di usare binding HTTP o WebHook, evitare l'esaurimento delle porte che può essere causato da un'errata creazione di istanze di HttpClient
. Per altre informazioni, vedere How to manage connections in Azure Functions (Come gestire le connessioni in Funzioni di Azure).
Riferimento a classi personalizzate
Se è necessario usare una classe Plain Old CLR Object (POCO) personalizzata, è possibile includere la definizione della classe all'interno dello stesso file o inserirla in un file separato.
Di seguito è riportato un esempio run.csx che include una definizione di classe POCO.
public static void Run(string myBlob, out MyClass myQueueItem)
{
log.Verbose($"C# Blob trigger function processed: {myBlob}");
myQueueItem = new MyClass() { Id = "myid" };
}
public class MyClass
{
public string Id { get; set; }
}
Una classe POCO deve avere un metodo Get e un metodo Set definiti per ogni proprietà.
Riutilizzo del codice CSX
È possibile usare classi e metodi definiti in altri file con estensione .csx nel file run.csx. A questo scopo, usare direttive #load
nel file run.csx. Nell'esempio seguente, una routine di registrazione denominata MyLogger
viene condivisa in myLogger.csx e caricata in run.csx usando la direttiva #load
:
Esempio di run.csx:
#load "mylogger.csx"
using Microsoft.Extensions.Logging;
public static void Run(TimerInfo myTimer, ILogger log)
{
log.LogInformation($"Log by run.csx: {DateTime.Now}");
MyLogger(log, $"Log by MyLogger: {DateTime.Now}");
}
Esempio di mylogger.csx:
public static void MyLogger(ILogger log, string logtext)
{
log.LogInformation(logtext);
}
L'uso di un file con estensione csx condiviso è una prassi comune quando si vuole tipizzare fortemente i dati passati tra le funzioni usando un oggetto POCO. Nell'esempio semplificato seguente, un trigger HTTP e un trigger della coda condividono un oggetto POCO denominato Order
per tipizzare fortemente i dati dell'ordine:
File run.csx di esempio per il trigger HTTP:
#load "..\shared\order.csx"
using System.Net;
using Microsoft.Extensions.Logging;
public static async Task<HttpResponseMessage> Run(Order req, IAsyncCollector<Order> outputQueueItem, ILogger log)
{
log.LogInformation("C# HTTP trigger function received an order.");
log.LogInformation(req.ToString());
log.LogInformation("Submitting to processing queue.");
if (req.orderId == null)
{
return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
else
{
await outputQueueItem.AddAsync(req);
return new HttpResponseMessage(HttpStatusCode.OK);
}
}
File run.csx di esempio per il trigger della coda:
#load "..\shared\order.csx"
using System;
using Microsoft.Extensions.Logging;
public static void Run(Order myQueueItem, out Order outputQueueItem, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed order...");
log.LogInformation(myQueueItem.ToString());
outputQueueItem = myQueueItem;
}
File order.csx di esempio:
public class Order
{
public string orderId {get; set; }
public string custName {get; set;}
public string custAddress {get; set;}
public string custEmail {get; set;}
public string cartId {get; set; }
public override String ToString()
{
return "\n{\n\torderId : " + orderId +
"\n\tcustName : " + custName +
"\n\tcustAddress : " + custAddress +
"\n\tcustEmail : " + custEmail +
"\n\tcartId : " + cartId + "\n}";
}
}
È possibile usare un percorso relativo con la direttiva #load
:
#load "mylogger.csx"
carica un file che si trova nella cartella della funzione.#load "loadedfiles\mylogger.csx"
carica un file che si trova in una sottocartella della cartella della funzione.#load "..\shared\mylogger.csx"
carica un file che si trova in una cartella allo stesso livello della cartella della funzione, ovvero direttamente in wwwroot.
La direttiva #load
è compatibile solo con i file con estensione .csx e non lo è con i file con estensione .cs.
Associazione al valore restituito dal metodo
È possibile usare un valore restituito del metodo per un'associazione di output, usando il nome $return
in function.json.
{
"name": "$return",
"type": "blob",
"direction": "out",
"path": "output-container/{id}"
}
Ecco il codice script C# usando il valore restituito, seguito da un esempio asincrono:
public static string Run(WorkItem input, ILogger log)
{
string json = string.Format("{{ \"id\": \"{0}\" }}", input.Id);
log.LogInformation($"C# script processed queue message. Item={json}");
return json;
}
public static Task<string> Run(WorkItem input, ILogger log)
{
string json = string.Format("{{ \"id\": \"{0}\" }}", input.Id);
log.LogInformation($"C# script processed queue message. Item={json}");
return Task.FromResult(json);
}
Usare il valore restituito solo se la corretta esecuzione di una funzione restituisce sempre un valore da passare all'associazione di output. In caso contrario, usare ICollector
o IAsyncCollector
, come illustrato nella sezione seguente.
Scrittura di più valori di output
Per scrivere più valori in un'associazione di output o se una chiamata corretta alla funzione potrebbe non restituire alcun valore da passare all'associazione di output, usare i tipi ICollector
o IAsyncCollector
. Questi tipi sono raccolte di sola scrittura che vengono scritte nell'associazione di output durante il completamento del metodo.
Questo esempio scrive più messaggi in coda nella stessa coda usando ICollector
:
public static void Run(ICollector<string> myQueue, ILogger log)
{
myQueue.Add("Hello");
myQueue.Add("World!");
}
Registrazione
Per registrare l'output nei log in streaming in C#, includere un argomento di tipo ILogger. È consigliabile denominarlo log
. Evitare di usare Console.Write
in Funzioni di Azure.
public static void Run(string myBlob, ILogger log)
{
log.LogInformation($"C# Blob trigger function processed: {myBlob}");
}
Nota
Per informazioni su un framework di registrazione più recente che è possibile usare invece di TraceWriter
, vedere la documentazione di ILogger nella Guida per sviluppatori della libreria di classi .NET.
Registrazione delle metriche personalizzate
È possibile usare il metodo di estensione LogMetric
in ILogger
per creare metriche personalizzate in Application Insights. Ecco un esempio di chiamata al metodo:
logger.LogMetric("TestMetric", 1234);
Questo codice è un'alternativa alla chiamata di TrackMetric
con l'API di Application Insights per .NET.
Async
Per rendere una funzione asincrona, usare la parola chiave async
e restituire un oggetto Task
.
public async static Task ProcessQueueMessageAsync(
string blobName,
Stream blobInput,
Stream blobOutput)
{
await blobInput.CopyToAsync(blobOutput, 4096);
}
Non è possibile usare i parametri out
in funzioni asincrone. Per le associazioni di output, usare invece il valore restituito di funzione o un oggetto agente di raccolta.
Token di annullamento
Una funzione può accettare un parametro CancellationToken, che consente al sistema operativo di notificare il codice quando la funzione sta per essere terminata. È possibile usare questa notifica per assicurarsi che la funzione non termini in modo imprevisto lasciando i dati in uno stato incoerente.
L'esempio seguente illustra come verificare l'eventuale imminente interruzione della funzione.
using System;
using System.IO;
using System.Threading;
public static void Run(
string inputText,
TextWriter logger,
CancellationToken token)
{
for (int i = 0; i < 100; i++)
{
if (token.IsCancellationRequested)
{
logger.WriteLine("Function was cancelled at iteration {0}", i);
break;
}
Thread.Sleep(5000);
logger.WriteLine("Normal processing for queue message={0}", inputText);
}
}
Importazione di spazi dei nomi
Se è necessario importare spazi dei nomi, è possibile farlo come al solito con la clausola using
.
using System.Net;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
public static Task<HttpResponseMessage> Run(HttpRequestMessage req, ILogger log)
Gli spazi dei nomi seguenti vengono importati automaticamente e sono quindi facoltativi:
System
System.Collections.Generic
System.IO
System.Linq
System.Net.Http
System.Threading.Tasks
Microsoft.Azure.WebJobs
Microsoft.Azure.WebJobs.Host
Riferimento ad assembly esterni
Per gli assembly di framework aggiungere riferimenti usando la direttiva #r "AssemblyName"
.
#r "System.Web.Http"
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
public static Task<HttpResponseMessage> Run(HttpRequestMessage req, ILogger log)
Gli assembly seguenti vengono 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
È possibile fare riferimento agli assembly seguenti con il nome semplice, in base alla versione del runtime:
Nel codice, agli assembly viene fatto riferimento come nell'esempio seguente:
#r "AssemblyName"
Fare riferimento ad assembly personalizzati
Per fare riferimento a un assembly personalizzato, è possibile usare un assembly condiviso o un assembly privato:
Gli assembly condivisi sono condivisi da tutte le funzioni all'interno di un'app di funzione. Per fare riferimento a un assembly personalizzato, caricare l'assembly nella cartella denominata
bin
nella cartella radice (wwwroot) dell'app per le funzioni.Gli assembly privati fanno parte del contesto di una funzione specificata e supportano il caricamento laterale di versioni diverse. Gli assembly privati devono essere caricati in una cartella
bin
nella directory di funzione. Fare riferimento agli assembly usando il nome del file, ad esempio#r "MyAssembly.dll"
.
Per informazioni su come caricare i file nella cartella della funzione, vedere la sezione sulla gestione dei pacchetti.
Directory controllate
La directory che contiene il file di script della funzione viene controllata automaticamente per le modifiche agli assembly. Per controllare le modifiche agli assembly in altre directory, aggiungerle all'elenco watchDirectories
in host.json.
Uso dei pacchetti NuGet
Il modo in cui entrambi i pacchetti di estensione di associazione e altri pacchetti NuGet vengono aggiunti all'app per le funzioni dipende dalla versione di destinazione del runtime di Funzioni.
Per impostazione predefinita, il set supportato di pacchetti NuGet dell'estensione Funzioni viene reso disponibile per l'app per le funzioni script C# usando bundle di estensioni. Per altre informazioni, vedere Bundle di estensioni.
Se per qualche motivo non è possibile usare bundle di estensioni nel progetto, è anche possibile usare Azure Functions Core Tools per installare le estensioni in base alle associazioni definite nei file function.json nell'app. Quando si usano Core Tools per registrare le estensioni, assicurarsi di usare l'opzione --csx
. Per altre informazioni, vedere Installazione delle estensioni func.
Per impostazione predefinita, Core Tools legge i file di function.json e aggiunge i pacchetti necessari a un file di progetto della libreria di classi C# extensions.csproj nella radice del file system dell'app per le funzioni (wwwroot). Poiché Core Tools usa dotnet.exe, è possibile usarlo per aggiungere qualsiasi riferimento al pacchetto NuGet a questo file di estensioni. Durante l'installazione, Core Tools compila extensions.csproj per installare le librerie necessarie. Di seguito è riportato un esempio di file extensions.csproj che aggiunge un riferimento a Microsoft.ProjectOxford.Face versione 1.1.0:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ProjectOxford.Face" Version="1.1.0" />
</ItemGroup>
</Project>
Nota
Per lo script C# (.csx), è necessario impostare TargetFramework
su un valore di netstandard2.0
. Altri framework di destinazione, ad esempio net6.0
, non sono supportati.
Per usare un feed NuGet personalizzato, specificare il feed in un Nuget.Config nella cartella radice dell'app per le funzioni. Per altre informazioni, vedere Configuring NuGet behavior (Configurazione del comportamento di NuGet).
Se si usa il progetto solo nel portale, è necessario creare manualmente il file extensions.csproj o un file Nuget.Config direttamente nel sito. Per altre informazioni, vedere Installare manualmente le estensioni.
Variabili di ambiente
Per ottenere una variabile di ambiente o un valore di impostazione dell'app, usare System.Environment.GetEnvironmentVariable
come illustrato nell'esempio di codice seguente:
public static void Run(TimerInfo myTimer, 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);
}
Criteri di ripetizione dei tentativi
Funzioni supporta due criteri di ripetizione dei tentativi predefiniti. Per altre informazioni, vedere il Criteri di ripetizione dei tentativi.
Ecco i criteri di ripetizione dei nel file function.json:
{
"disabled": false,
"bindings": [
{
....
}
],
"retry": {
"strategy": "fixedDelay",
"maxRetryCount": 4,
"delayInterval": "00:00:10"
}
}
Proprietà di function.json | Descrizione |
---|---|
aziendale | Usare fixedDelay . |
maxRetryCount | Obbligatorio. Numero massimo di tentativi consentiti per ogni esecuzione di funzione. -1 significa riprovare per un periodo illimitato. |
delayInterval | Ritardo usato tra i tentativi. Specificarlo come stringa con il formato HH:mm:ss . |
Associazione in fase di esecuzione
In C# e altri linguaggi .NET, è possibile usare un metodo di associazione imperativa anziché dichiarativa in function.json. L'associazione imperativa è utile quando i parametri di associazione devono essere calcolati in fase di runtime invece che in fase di progettazione. Con questo modello è possibile associare rapidamente i dati ad associazioni di input e output supportate nel codice della funzione.
Definire un'associazione imperativa, come segue:
- Non includere una voce in function.json per le associazioni imperative da eseguire.
- Passare un parametro di input
Binder binder
oIBinder binder
. - Usare il seguente modello C# per eseguire l'associazione dati.
using (var output = await binder.BindAsync<T>(new BindingTypeAttribute(...)))
{
...
}
BindingTypeAttribute
è l'attributo .NET che definisce l'associazione e T
è un tipo di input o output supportato da quel tipo di associazione. T
non può essere un tipo di parametro out
(ad esempio out JObject
). L'associazione di output della tabella App per dispositivi mobili, ad esempio, supporta sei tipi di output, ma è possibile usare solo ICollector<T> o IAsyncCollector<T>
per T
.
Esempio con un solo attributo
L'esempio di codice seguente crea un associazione di output del BLOB di archiviazione con percorso del BLOB definito in fase di esecuzione, quindi scrive una stringa per il BLOB.
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host.Bindings.Runtime;
public static async Task Run(string input, Binder binder)
{
using (var writer = await binder.BindAsync<TextWriter>(new BlobAttribute("samples-output/path")))
{
writer.Write("Hello World!!");
}
}
BlobAttribute definisce l'associazione di input o output del BLOB di archiviazione e TextWriter è un tipo di associazione di output supportato.
Esempio con più attributi
L'esempio precedente ottiene l'impostazione dell'app per la stringa di connessione dell'account di archiviazione principale dell'app, ovvero AzureWebJobsStorage
. È possibile specificare un'impostazione app personalizzata da usare per l'account di archiviazione aggiungendo StorageAccountAttribute e passando la matrice di attributi in BindAsync<T>()
. Usare un parametro Binder
e non IBinder
. Ad esempio:
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host.Bindings.Runtime;
public static async Task Run(string input, Binder binder)
{
var attributes = new Attribute[]
{
new BlobAttribute("samples-output/path"),
new StorageAccountAttribute("MyStorageAccount")
};
using (var writer = await binder.BindAsync<TextWriter>(attributes))
{
writer.Write("Hello World!");
}
}
Nella tabella seguente vengono elencati gli attributi .NET per ogni tipo di associazione e i pacchetti in cui sono definiti.
Convertire un'app script C# in un progetto C#
Il modo più semplice per convertire un'app per le funzioni script C# in un progetto di libreria di classi C# compilato consiste nell'iniziare con un nuovo progetto. È quindi possibile, per ogni funzione, eseguire la migrazione del codice e della configurazione da ogni file run.csx e function.json file in una cartella di funzioni a un singolo nuovo file di codice della libreria di classi .cs. Ad esempio, quando si dispone di una funzione script C# denominata HelloWorld
, si avranno due file: HelloWorld/run.csx
e HelloWorld/function.json
. Per questa funzione, si crea un file di codice denominato HelloWorld.cs
nel nuovo progetto di libreria di classi.
Se si usa lo script C# per la modifica del portale, è possibile scaricare il contenuto dell'app nel computer locale. Scegliere l'opzione Contenuto del sito anziché Contenuto e progetto di Visual Studio. Non è necessario generare un progetto e non includere le impostazioni dell'applicazione nel download. Si sta definendo un nuovo ambiente di sviluppo e questo ambiente non deve avere le stesse autorizzazioni dell'ambiente app ospitato.
Queste istruzioni illustrano come convertire le funzioni script C# (eseguite In-Process con l'host funzioni) in funzioni della libreria di classi C# eseguite in un processo di lavoro isolato.
Completare la sezione Creare un progetto di app per le funzioni nell'avvio rapido preferito:
Se il codice di script C# originale include un file
extensions.csproj
o qualsiasi filefunction.proj
, copiare i riferimenti al pacchetto da questi file e aggiungerli al file.csproj
del nuovo progetto nello stessoItemGroup
con le dipendenze principali di Funzioni.Suggerimento
La conversione offre una buona opportunità per eseguire l'aggiornamento alle versioni più recenti delle dipendenze. In questo modo potrebbero essere necessarie ulteriori modifiche al codice in un passaggio successivo.
Copiare il contenuto del file originale
host.json
nel filehost.json
del nuovo progetto, ad eccezione della sezioneextensionBundles
(i progetti C# compilati non usano bundle di estensioni ed è necessario aggiungere in modo esplicito riferimenti a tutte le estensioni usate dalle funzioni). Quando si uniscono host.json file, tenere presente che lo schemahost.json
viene sottoposto a controllo delle versioni, con la maggior parte delle app che usano la versione 2.0. Il contenuto della sezioneextensions
può differire in base a versioni specifiche delle estensioni di associazione usate dalle funzioni. Vedere singoli articoli di riferimento sulle estensioni per informazioni su come configurare correttamente il host.json per le versioni specifiche.Per eventuali file condivisi a cui fa riferimento una direttiva
#load
, creare un nuovo file.cs
per ognuno di questi riferimenti condivisi. È più semplice creare un nuovo file.cs
per ogni definizione di classe condivisa. Se sono presenti metodi statici senza una classe, è necessario definire nuove classi per questi metodi.Eseguire le attività seguenti per ogni cartella
<FUNCTION_NAME>
nel progetto originale:Creare un nuovo file denominato
<FUNCTION_NAME>.cs
, sostituendo<FUNCTION_NAME>
con il nome della cartella che ha definito la funzione script C#. È possibile creare un nuovo file di codice della funzione da uno dei modelli specifici del trigger nel modo seguente:Usando il comando
func new --name <FUNCTION_NAME>
e scegliendo il modello di trigger corretto al prompt.Copiare le istruzioni
using
dal filerun.csx
e aggiungerle al nuovo file. Non sono necessarie direttive#r
.Per eventuali istruzioni
#load
nel filerun.csx
, aggiungere una nuova istruzioneusing
per lo spazio dei nomi usato per il codice condiviso.Nel nuovo file definire una classe per la funzione nello spazio dei nomi usato per il progetto.
Creare un nuovo metodo denominato
RunHandler
o simile. Questo nuovo metodo funge da nuovo punto di ingresso per la funzione.Copiare il metodo statico che rappresenta la funzione, insieme alle funzioni chiamate, da
run.csx
alla nuova classe come secondo metodo. Dal nuovo metodo creato nel passaggio precedente chiamare questo metodo statico. Questo passaggio di riferimento indiretto è utile per esplorare eventuali differenze durante la continuazione dell'aggiornamento. È possibile mantenere esattamente lo stesso metodo originale e controllare semplicemente gli input dal nuovo contesto. Potrebbe essere necessario creare parametri nel nuovo metodo che viene quindi passato alla chiamata al metodo statico. Dopo aver confermato che la migrazione ha funzionato come previsto, è possibile rimuovere questo livello aggiuntivo di riferimento indiretto.Per ogni associazione nel file
function.json
, aggiungere l'attributo corrispondente al nuovo metodo. Per trovare rapidamente esempi di associazione, vedere Aggiungere manualmente associazioni basate su esempi.Aggiungere eventuali pacchetti di estensione richiesti dalle associazioni al progetto, se non è già stato fatto.
Ricreare le impostazioni dell'applicazione richieste dall'app nella raccolta
Values
del file local.settings.json.Verificare che il progetto venga eseguito in locale:
Usare
func start
per eseguire l'app dalla riga di comando. Per altre informazioni, vedere Eseguire funzioni in locale.Pubblicare il progetto in una nuova app per le funzioni in Azure:
Creare le risorse di Azure e distribuire il progetto di codice in Azure usando il comando
func azure functionapp publish <APP_NAME>
. Per altre informazioni, vedere Distribuire i file di progetto.
Conversione di funzioni di esempio
Questa sezione illustra un esempio della migrazione per una singola funzione.
La funzione originale nello script C# ha due file:
HelloWorld/function.json
HelloWorld/run.csx
Di seguito è riportato il contenuto del file HelloWorld/function.json
:
{
"bindings": [
{
"authLevel": "FUNCTION",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
}
]
}
Di seguito è riportato il contenuto del file HelloWorld/run.csx
:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
string responseMessage = string.IsNullOrEmpty(name)
? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
: $"Hello, {name}. This HTTP triggered function executed successfully.";
return new OkObjectResult(responseMessage);
}
Dopo la migrazione al modello di lavoro isolato con integrazione di ASP.NET Core, questi vengono sostituiti da un singolo HelloWorld.cs
:
using System.Net;
using Microsoft.Azure.Functions.Worker;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
namespace MyFunctionApp
{
public class HelloWorld
{
private readonly ILogger _logger;
public HelloWorld(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<HelloWorld>();
}
[Function("HelloWorld")]
public async Task<IActionResult> RunHandler([HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req)
{
return await Run(req, _logger);
}
// From run.csx
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
string responseMessage = string.IsNullOrEmpty(name)
? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
: $"Hello, {name}. This HTTP triggered function executed successfully.";
return new OkObjectResult(responseMessage);
}
}
}
Configurazione di associazione ed esempi
Questa sezione contiene riferimenti ed esempi per la definizione di trigger e associazioni nello script C#.
Trigger di BLOB
Nella tabella seguente sono illustrate le proprietà di configurazione dell'associazione per lo script C# impostate nel file function.json.
Proprietà di function.json | Descrizione |
---|---|
type | Deve essere impostato su blobTrigger . Questa proprietà viene impostata automaticamente quando si crea il trigger nel portale di Azure. |
direction | Deve essere impostato su in . Questa proprietà viene impostata automaticamente quando si crea il trigger nel portale di Azure. |
name | Nome della variabile che rappresenta il BLOB nel codice della funzione. |
path | Contenitore da monitorare. Può essere un modello di nome per il BLOB. |
connection | Nome di un'impostazione o di una raccolta di impostazioni dell'app che specifica come connettersi ai BLOB di Azure. Vedere Connessioni. |
L'esempio seguente illustra una definizione di trigger di BLOB in un file function.json e il codice che usa l'associazione. La funzione scrive un log quando viene aggiunto o aggiornato un BLOB nel samples-workitems
contenitore.
Ecco i dati di associazione nel file function.json:
{
"disabled": false,
"bindings": [
{
"name": "myBlob",
"type": "blobTrigger",
"direction": "in",
"path": "samples-workitems/{name}",
"connection":"MyStorageAccountAppSetting"
}
]
}
La stringa {name}
nel percorso del trigger di BLOB samples-workitems/{name}
crea un'espressione di associazione che può essere usata nel codice della funzione per accedere al nome file del BLOB di attivazione. Per altre informazioni, vedere Criteri sui nomi BLOB.
Ecco il codice script C# associato a un oggetto Stream
:
public static void Run(Stream myBlob, string name, ILogger log)
{
log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes");
}
Ecco il codice script C# associato a un oggetto CloudBlockBlob
:
#r "Microsoft.WindowsAzure.Storage"
using Microsoft.WindowsAzure.Storage.Blob;
public static void Run(CloudBlockBlob myBlob, string name, ILogger log)
{
log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name}\nURI:{myBlob.StorageUri}");
}
Input BLOB
Nella tabella seguente sono illustrate le proprietà di configurazione dell'associazione per lo script C# impostate nel file function.json.
Proprietà di function.json | Descrizione |
---|---|
type | Deve essere impostato su blob . |
direction | Deve essere impostato su in . |
name | Nome della variabile che rappresenta il BLOB nel codice della funzione. |
path | Percorso del BLOB. |
connection | Nome di un'impostazione o di una raccolta di impostazioni dell'app che specifica come connettersi ai BLOB di Azure. Vedere Connessioni. |
L'esempio seguente mostra associazioni di input e di output di BLOB in un file function.json e codice script C# che usa le associazioni. La funzione crea una copia di un BLOB di testo. La funzione viene attivata da un messaggio della coda che contiene il nome del BLOB da copiare. Il nuovo BLOB è denominato {originalblobname}-Copy.
Nel file function.json viene usata la proprietà dei metadati queueTrigger
per specificare il nome del BLOB nelle proprietà path
:
{
"bindings": [
{
"queueName": "myqueue-items",
"connection": "MyStorageConnectionAppSetting",
"name": "myQueueItem",
"type": "queueTrigger",
"direction": "in"
},
{
"name": "myInputBlob",
"type": "blob",
"path": "samples-workitems/{queueTrigger}",
"connection": "MyStorageConnectionAppSetting",
"direction": "in"
},
{
"name": "myOutputBlob",
"type": "blob",
"path": "samples-workitems/{queueTrigger}-Copy",
"connection": "MyStorageConnectionAppSetting",
"direction": "out"
}
],
"disabled": false
}
Ecco il codice script C#:
public static void Run(string myQueueItem, string myInputBlob, out string myOutputBlob, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
myOutputBlob = myInputBlob;
}
Output BLOB
Nella tabella seguente sono illustrate le proprietà di configurazione dell'associazione per lo script C# impostate nel file function.json.
Proprietà di function.json | Descrizione |
---|---|
type | Deve essere impostato su blob . |
direction | Deve essere impostato su out . |
name | Nome della variabile che rappresenta il BLOB nel codice della funzione. |
path | Percorso del BLOB. |
connection | Nome di un'impostazione o di una raccolta di impostazioni dell'app che specifica come connettersi ai BLOB di Azure. Vedere Connessioni. |
L'esempio seguente mostra associazioni di input e di output di BLOB in un file function.json e codice script C# che usa le associazioni. La funzione crea una copia di un BLOB di testo. La funzione viene attivata da un messaggio della coda che contiene il nome del BLOB da copiare. Il nuovo BLOB è denominato {originalblobname}-Copy.
Nel file function.json viene usata la proprietà dei metadati queueTrigger
per specificare il nome del BLOB nelle proprietà path
:
{
"bindings": [
{
"queueName": "myqueue-items",
"connection": "MyStorageConnectionAppSetting",
"name": "myQueueItem",
"type": "queueTrigger",
"direction": "in"
},
{
"name": "myInputBlob",
"type": "blob",
"path": "samples-workitems/{queueTrigger}",
"connection": "MyStorageConnectionAppSetting",
"direction": "in"
},
{
"name": "myOutputBlob",
"type": "blob",
"path": "samples-workitems/{queueTrigger}-Copy",
"connection": "MyStorageConnectionAppSetting",
"direction": "out"
}
],
"disabled": false
}
Ecco il codice script C#:
public static void Run(string myQueueItem, string myInputBlob, out string myOutputBlob, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
myOutputBlob = myInputBlob;
}
Trigger RabbitMQ
L'esempio seguente mostra un'associazione di trigger RabbitMQ in un file function.json e una funzione script C# che usa l'associazione. La funzione legge e registra il messaggio RabbitMQ.
Ecco i dati di associazione nel file function.json:
{
"bindings": [
{
"name": "myQueueItem",
"type": "rabbitMQTrigger",
"direction": "in",
"queueName": "queue",
"connectionStringSetting": "rabbitMQConnectionAppSetting"
}
]
}
Ecco il codice script C#:
using System;
public static void Run(string myQueueItem, ILogger log)
{
log.LogInformation($"C# Script RabbitMQ trigger function processed: {myQueueItem}");
}
Trigger di accodamento
Nella tabella seguente sono illustrate le proprietà di configurazione dell'associazione per lo script C# impostate nel file function.json.
Proprietà di function.json | Descrizione |
---|---|
type | Deve essere impostato su queueTrigger . Questa proprietà viene impostata automaticamente quando si crea il trigger nel portale di Azure. |
direction | Solo nel file function.json. Deve essere impostato su in . Questa proprietà viene impostata automaticamente quando si crea il trigger nel portale di Azure. |
name | Nome della variabile che contiene il payload dell'elemento della coda nel codice della funzione. |
queueName | Nome della coda sulla quale eseguire il polling. |
connection | Nome di un'impostazione o di una raccolta di impostazioni dell'app che specifica come connettersi alle Code di Azure. Vedere Connessioni. |
L'esempio seguente illustra un'associazione di trigger della coda in un file function.json e il codice script C# che usa l'associazione. La funzione esegue il polling della coda myqueue-items
e scrive un log a ogni elaborazione di un elemento della coda.
Ecco il file function.json:
{
"disabled": false,
"bindings": [
{
"type": "queueTrigger",
"direction": "in",
"name": "myQueueItem",
"queueName": "myqueue-items",
"connection":"MyStorageConnectionAppSetting"
}
]
}
Ecco il codice script C#:
#r "Microsoft.WindowsAzure.Storage"
using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage.Queue;
using System;
public static void Run(CloudQueueMessage myQueueItem,
DateTimeOffset expirationTime,
DateTimeOffset insertionTime,
DateTimeOffset nextVisibleTime,
string queueTrigger,
string id,
string popReceipt,
int dequeueCount,
ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem.AsString}\n" +
$"queueTrigger={queueTrigger}\n" +
$"expirationTime={expirationTime}\n" +
$"insertionTime={insertionTime}\n" +
$"nextVisibleTime={nextVisibleTime}\n" +
$"id={id}\n" +
$"popReceipt={popReceipt}\n" +
$"dequeueCount={dequeueCount}");
}
Output di coda
Nella tabella seguente sono illustrate le proprietà di configurazione dell'associazione per lo script C# impostate nel file function.json.
Proprietà di function.json | Descrizione |
---|---|
type | Deve essere impostato su queue . Questa proprietà viene impostata automaticamente quando si crea il trigger nel portale di Azure. |
direction | Deve essere impostato su out . Questa proprietà viene impostata automaticamente quando si crea il trigger nel portale di Azure. |
name | Nome della variabile che rappresenta la coda nel codice della funzione. Impostare su $return per fare riferimento al valore restituito della funzione. |
queueName | Nome della coda. |
connection | Nome di un'impostazione o di una raccolta di impostazioni dell'app che specifica come connettersi alle Code di Azure. Vedere Connessioni. |
L'esempio seguente illustra un'associazione di trigger HTTP in un file function.json e il codice script C# che usa l'associazione. La funzione crea un elemento della coda con un payload dell'oggetto CustomQueueMessage per ogni richiesta HTTP ricevuta.
Ecco il file function.json:
{
"bindings": [
{
"type": "httpTrigger",
"direction": "in",
"authLevel": "function",
"name": "input"
},
{
"type": "http",
"direction": "out",
"name": "$return"
},
{
"type": "queue",
"direction": "out",
"name": "$return",
"queueName": "outqueue",
"connection": "MyStorageConnectionAppSetting"
}
]
}
Ecco il codice script C# che crea un singolo messaggio nella coda:
public class CustomQueueMessage
{
public string PersonName { get; set; }
public string Title { get; set; }
}
public static CustomQueueMessage Run(CustomQueueMessage input, ILogger log)
{
return input;
}
È possibile inviare più messaggi contemporaneamente usando ICollector
o il parametro IAsyncCollector
. Ecco il codice script C# che invia più messaggi, uno con i dati della richiesta HTTP e uno con i valori hardcoded:
public static void Run(
CustomQueueMessage input,
ICollector<CustomQueueMessage> myQueueItems,
ILogger log)
{
myQueueItems.Add(input);
myQueueItems.Add(new CustomQueueMessage { PersonName = "You", Title = "None" });
}
Input tabella
Questa sezione descrive esclusivamente il supporto per la versione dell'API Tables dell'estensione.
Nella tabella seguente sono illustrate le proprietà di configurazione dell'associazione per lo script C# impostate nel file function.json.
Proprietà di function.json | Descrizione |
---|---|
type | Deve essere impostato su table . Questa proprietà viene impostata automaticamente quando si crea l'associazione nel portale di Azure. |
direction | Deve essere impostato su in . Questa proprietà viene impostata automaticamente quando si crea l'associazione nel portale di Azure. |
name | Nome della variabile che rappresenta la tabella o l'entità nel codice della funzione. |
tableName | Nome della tabella. |
partitionKey | Facoltativo. Chiave di partizione dell'entità della tabella da leggere. |
rowKey | Facoltativo. Chiave di riga dell'entità della tabella da leggere. Non può essere usata con take o filter . |
take | Facoltativo. Numero massimo di entità da restituire. Non può essere usato con rowKey . |
filter | Facoltativo. Espressione di filtro OData per le entità da restituire dalla tabella. Non può essere usato con rowKey . |
connection | Nome di un'impostazione o di una raccolta di impostazioni dell'app che specifica come connettersi al servizio tabelle. Vedere Connessioni. |
L'esempio seguente illustra un'associazione di input della tabella in un file function.json e codice script C# che usa l'associazione. La funzione usa un trigger della coda per leggere una riga della tabella.
Il file function.json specifica partitionKey
e rowKey
. Il valore rowKey
{queueTrigger}
indica che la chiave di riga proviene dalla stringa di messaggio della coda.
{
"bindings": [
{
"queueName": "myqueue-items",
"connection": "MyStorageConnectionAppSetting",
"name": "myQueueItem",
"type": "queueTrigger",
"direction": "in"
},
{
"name": "personEntity",
"type": "table",
"tableName": "Person",
"partitionKey": "Test",
"rowKey": "{queueTrigger}",
"connection": "MyStorageConnectionAppSetting",
"direction": "in"
}
],
"disabled": false
}
Ecco il codice script C#:
#r "Azure.Data.Tables"
using Microsoft.Extensions.Logging;
using Azure.Data.Tables;
public static void Run(string myQueueItem, Person personEntity, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
log.LogInformation($"Name in Person entity: {personEntity.Name}");
}
public class Person : ITableEntity
{
public string Name { get; set; }
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public DateTimeOffset? Timestamp { get; set; }
public ETag ETag { get; set; }
}
Output tabella
Questa sezione descrive esclusivamente il supporto per la versione dell'API Tables dell'estensione.
Nella tabella seguente sono illustrate le proprietà di configurazione dell'associazione per lo script C# impostate nel file function.json.
Proprietà di function.json | Descrizione |
---|---|
type | Deve essere impostato su table . Questa proprietà viene impostata automaticamente quando si crea l'associazione nel portale di Azure. |
direction | Deve essere impostato su out . Questa proprietà viene impostata automaticamente quando si crea l'associazione nel portale di Azure. |
name | Nome della variabile usato nel codice della funzione che rappresenta la tabella o l'entità. Impostare su $return per fare riferimento al valore restituito della funzione. |
tableName | Nome della tabella in cui scrivere. |
partitionKey | Chiave di partizione dell'entità della tabella da scrivere. |
rowKey | Chiave di riga dell'entità della tabella da scrivere. |
connection | Nome di un'impostazione o di una raccolta di impostazioni dell'app che specifica come connettersi al servizio tabelle. Vedere Connessioni. |
L'esempio seguente illustra un'associazione di output della tabella in un file function.json e codice script C# che usa l'associazione. La funzione scrive più entità della tabella.
Ecco il file function.json:
{
"bindings": [
{
"name": "input",
"type": "manualTrigger",
"direction": "in"
},
{
"tableName": "Person",
"connection": "MyStorageConnectionAppSetting",
"name": "tableBinding",
"type": "table",
"direction": "out"
}
],
"disabled": false
}
Ecco il codice script C#:
public static void Run(string input, ICollector<Person> tableBinding, ILogger log)
{
for (int i = 1; i < 10; i++)
{
log.LogInformation($"Adding Person entity {i}");
tableBinding.Add(
new Person() {
PartitionKey = "Test",
RowKey = i.ToString(),
Name = "Name" + i.ToString() }
);
}
}
public class Person
{
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public string Name { get; set; }
}
Trigger timer
Nella tabella seguente sono illustrate le proprietà di configurazione dell'associazione per lo script C# impostate nel file function.json.
Proprietà di function.json | Descrizione |
---|---|
type | Deve essere impostato su timerTrigger . Questa proprietà viene impostata automaticamente quando si crea il trigger nel portale di Azure. |
direction | Deve essere impostato su in . Questa proprietà viene impostata automaticamente quando si crea il trigger nel portale di Azure. |
name | Nome della variabile che rappresenta l'oggetto timer nel codice della funzione. |
schedule | Espressione CRON o valore TimeSpan. TimeSpan può essere usato solo per un'app per le funzioni in esecuzione in un piano di servizio app. È possibile inserire l'espressione schedule in un'impostazione dell'app e definire per questa proprietà il nome dell'impostazione dell'app racchiuso tra simboli %, come in questo esempio: "%ImpostazioneAppSchedule%". |
runOnStartup | Se true , la funzione viene richiamata all'avvio del runtime. Ad esempio, il runtime viene avviato quando l'app per le funzioni si riattiva dopo un periodo di inattività, quando l'app per le funzioni viene riavviata a causa di modifiche alla funzione e quando l'app per le funzioni viene scalata orizzontalmente. Usare con cautela. runOnStartup dovrebbe quindi essere impostato su true solo in rari casi o mai, specialmente in ambienti di produzione. |
useMonitor | Impostata su true o false per indicare se monitorare la pianificazione. Il monitoraggio della pianificazione rende persistenti le occorrenze della pianificazione per garantire che la pianificazione venga gestita correttamente anche quando le istanze dell'app per le funzioni vengono riavviate. Se la proprietà non è impostata in modo esplicito, il valore predefinito è true per le pianificazioni che hanno un intervallo di ricorrenza superiore o uguale a 1 minuto. Per le pianificazioni attivate più di una volta al minuto, il valore predefinito è false . |
L'esempio seguente mostra un'associazione di trigger timer in un file function.json e una funzione script C# che usa l'associazione. La funzione scrive un log che indica se la chiamata di funzione è dovuta un'occorrenza di pianificazione mancante. L'oggetto TimerInfo
viene passato alla funzione.
Ecco i dati di associazione nel file function.json:
{
"schedule": "0 */5 * * * *",
"name": "myTimer",
"type": "timerTrigger",
"direction": "in"
}
Ecco il codice script C#:
public static void Run(TimerInfo myTimer, ILogger log)
{
if (myTimer.IsPastDue)
{
log.LogInformation("Timer is running late!");
}
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}" );
}
Trigger HTTP
Nella tabella seguente sono illustrate le proprietà di configurazione del trigger impostate nel file function.json:
Proprietà di function.json | Descrizione |
---|---|
type | Obbligatoria. Deve essere impostata su httpTrigger . |
direction | Obbligatoria. Deve essere impostata su in . |
name | Obbligatoria. Nome della variabile usato nel codice della funzione per la richiesta o il corpo della richiesta. |
authLevel | Determina le eventuali chiavi che devono essere presenti nella richiesta per richiamare la funzione. Per i valori supportati, vedere Livello di autorizzazione. |
methods | Matrice di metodi HTTP a cui la funzione risponde. Se non viene specificata, la funzione risponde a tutti i metodi HTTP. Vedere Personalizzare l'endpoint HTTP. |
route | Definisce il modello di route, controllando a quali URL di richiesta risponde la funzione. Il valore predefinito, se non ne viene specificato nessuno, è <functionname> . Per altre informazioni, vedere Personalizzare l'endpoint HTTP. |
webHookType | Supportato solo per la versione di runtime 1.x. Configura il trigger HTTP perché funga da ricevitore webhook per il provider specificato. Per i valori supportati, vedere Tipo di webhook. |
L'esempio seguente mostra un'associazione di trigger in un file function.json e una funzione script C# che usa l'associazione. La funzione cerca un parametro name
nella stringa di query o nel corpo della richiesta HTTP.
Ecco il file function.json:
{
"disabled": false,
"bindings": [
{
"authLevel": "function",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
}
]
}
Ecco il codice script C# associato a un oggetto HttpRequest
:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = String.Empty;
using (StreamReader streamReader = new StreamReader(req.Body))
{
requestBody = await streamReader.ReadToEndAsync();
}
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
return name != null
? (ActionResult)new OkObjectResult($"Hello, {name}")
: new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}
È possibile associare a un oggetto personalizzato invece di HttpRequest
. Questo oggetto viene creato dal corpo della richiesta e analizzato come JSON. Analogamente, un tipo può essere passato all’associazione di output della risposta HTTP e restituito come corpo della risposta, con un codice di stato 200
.
using System.Net;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
public static string Run(Person person, ILogger log)
{
return person.Name != null
? (ActionResult)new OkObjectResult($"Hello, {person.Name}")
: new BadRequestObjectResult("Please pass an instance of Person.");
}
public class Person {
public string Name {get; set;}
}
Output HTTP
Nella tabella seguente sono illustrate le proprietà di configurazione dell'associazione impostate nel file function.json.
Proprietà | Descrizione |
---|---|
type | Deve essere impostato su http . |
direction | Deve essere impostato su out . |
name | Nome della variabile usato nel codice della funzione per la risposta, o $return per usare il valore restituito. |
Trigger per Hub eventi
Nella tabella seguente sono illustrate le proprietà di configurazione del trigger impostate nel file function.json:
Proprietà di function.json | Descrizione |
---|---|
type | Deve essere impostato su eventHubTrigger . Questa proprietà viene impostata automaticamente quando si crea il trigger nel portale di Azure. |
direction | Deve essere impostato su in . Questa proprietà viene impostata automaticamente quando si crea il trigger nel portale di Azure. |
name | Nome della variabile che rappresenta l'elemento evento nel codice della funzione. |
eventHubName | Funzioni 2.x e versioni successive. Nome di Hub eventi. Quando il nome dell'hub eventi è presente anche nella stringa di connessione, tale valore sostituisce questa proprietà in fase di runtime. È possibile farvi riferimento tramite le impostazioni dell'app %eventHubName% . Nella versione 1.x questa proprietà è denominata path . |
consumerGroup | Proprietà facoltativa usata per impostare il gruppo di consumer usato per effettuare la sottoscrizione agli eventi nell'hub. Se omessa, al suo posto viene usato il gruppo di consumer $Default . |
connection | Nome di un'impostazione o di una raccolta di impostazioni dell'app che specifica come connettersi a Hub eventi. Vedere Connessioni. |
L'esempio seguente mostra un'associazione di trigger per Hub eventi in un file function.json e una funzione script C# che usa l'associazione. La funzione registra il corpo del messaggio del trigger per Hub eventi.
Gli esempi seguenti mostrano i dati di associazione di Hub eventi nel file function.json per il runtime di Funzioni versione 2.x e successive.
{
"type": "eventHubTrigger",
"name": "myEventHubMessage",
"direction": "in",
"eventHubName": "MyEventHub",
"connection": "myEventHubReadConnectionAppSetting"
}
Ecco il codice script C#:
using System;
public static void Run(string myEventHubMessage, TraceWriter log)
{
log.Info($"C# function triggered to process a message: {myEventHubMessage}");
}
Per ottenere l'accesso ai metadati degli eventi nel codice della funzione, eseguire l'associazione a un oggetto EventData. È possibile anche accedere alle stesse proprietà usando le espressioni di associazione nella firma del metodo. Nell'esempio seguente vengono illustrati entrambi i modi per ottenere gli stessi dati:
#r "Microsoft.Azure.EventHubs"
using System.Text;
using System;
using Microsoft.ServiceBus.Messaging;
using Microsoft.Azure.EventHubs;
public void Run(EventData myEventHubMessage,
DateTime enqueuedTimeUtc,
Int64 sequenceNumber,
string offset,
TraceWriter log)
{
log.Info($"Event: {Encoding.UTF8.GetString(myEventHubMessage.Body)}");
log.Info($"EnqueuedTimeUtc={myEventHubMessage.SystemProperties.EnqueuedTimeUtc}");
log.Info($"SequenceNumber={myEventHubMessage.SystemProperties.SequenceNumber}");
log.Info($"Offset={myEventHubMessage.SystemProperties.Offset}");
// Metadata accessed by using binding expressions
log.Info($"EnqueuedTimeUtc={enqueuedTimeUtc}");
log.Info($"SequenceNumber={sequenceNumber}");
log.Info($"Offset={offset}");
}
Per ricevere gli eventi in un batch, impostare string
o EventData
come matrice:
public static void Run(string[] eventHubMessages, TraceWriter log)
{
foreach (var message in eventHubMessages)
{
log.Info($"C# function triggered to process a message: {message}");
}
}
Output di Hub eventi
Nella tabella seguente sono illustrate le proprietà di configurazione dell'associazione impostate nel file function.json.
Proprietà di function.json | Descrizione |
---|---|
type | Deve essere impostato su eventHub . |
direction | Deve essere impostato su out . Questo parametro viene impostato automaticamente quando si crea l'associazione nel portale di Azure. |
name | Nome della variabile usato nel codice della funzione che rappresenta l'evento. |
eventHubName | Funzioni 2.x e versioni successive. Nome di Hub eventi. Quando il nome dell'hub eventi è presente anche nella stringa di connessione, tale valore sostituisce questa proprietà in fase di runtime. In Funzioni 1.x questa proprietà è denominata path . |
connection | Nome di un'impostazione o di una raccolta di impostazioni dell'app che specifica come connettersi a Hub eventi. Per altre informazioni, vedere Connessioni. |
L'esempio seguente mostra un'associazione di trigger per Hub eventi in un file function.json e una funzione script C# che usa l'associazione. La funzione scrive un messaggio in un Hub eventi.
Gli esempi seguenti mostrano i dati di associazione di Hub eventi nel file function.json per il runtime di Funzioni versione 2.x e successive.
{
"type": "eventHub",
"name": "outputEventHubMessage",
"eventHubName": "myeventhub",
"connection": "MyEventHubSendAppSetting",
"direction": "out"
}
Ecco il codice script C# che crea un messaggio:
using System;
using Microsoft.Extensions.Logging;
public static void Run(TimerInfo myTimer, out string outputEventHubMessage, ILogger log)
{
String msg = $"TimerTriggerCSharp1 executed at: {DateTime.Now}";
log.LogInformation(msg);
outputEventHubMessage = msg;
}
Ecco il codice script C# che crea più messaggi:
public static void Run(TimerInfo myTimer, ICollector<string> outputEventHubMessage, ILogger log)
{
string message = $"Message created at: {DateTime.Now}";
log.LogInformation(message);
outputEventHubMessage.Add("1 " + message);
outputEventHubMessage.Add("2 " + message);
}
Trigger Griglia di eventi
Nella tabella seguente sono illustrate le proprietà di configurazione dell'associazione per lo script C# impostate nel file function.json. Non sono presenti parametri o proprietà di costruttori da impostare nell'attributo EventGridTrigger
.
Proprietà di function.json | Descrizione |
---|---|
type | Obbligatoria. Deve essere impostata su eventGridTrigger . |
direction | Obbligatoria. Deve essere impostata su in . |
name | Obbligatoria: nome della variabile usato nel codice della funzione per il parametro che riceve i dati dell'evento. |
L'esempio seguente mostra un trigger di Griglia di eventi definito nel file function.json.
Ecco i dati di associazione nel file function.json:
{
"bindings": [
{
"type": "eventGridTrigger",
"name": "eventGridEvent",
"direction": "in"
}
],
"disabled": false
}
Di seguito è riportato un esempio di funzione script C# che usa un parametro di associazione EventGridEvent
:
#r "Azure.Messaging.EventGrid"
using Azure.Messaging.EventGrid;
using Microsoft.Extensions.Logging;
public static void Run(EventGridEvent eventGridEvent, ILogger log)
{
log.LogInformation(eventGridEvent.Data.ToString());
}
Di seguito è riportato un esempio di funzione script C# che usa un parametro di associazione JObject
:
#r "Newtonsoft.Json"
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public static void Run(JObject eventGridEvent, TraceWriter log)
{
log.Info(eventGridEvent.ToString(Formatting.Indented));
}
Output di Griglia di eventi
Nella tabella seguente sono illustrate le proprietà di configurazione dell'associazione per lo script C# impostate nel file function.json.
Proprietà di function.json | Descrizione |
---|---|
type | Deve essere impostato su eventGrid . |
direction | Deve essere impostato su out . Questo parametro viene impostato automaticamente quando si crea l'associazione nel portale di Azure. |
name | Nome della variabile usato nel codice della funzione che rappresenta l'evento. |
topicEndpointUri | Nome di un'impostazione di app che contiene l'URI per l'argomento personalizzato, ad esempio MyTopicEndpointUri . |
topicKeySetting | Nome di un'impostazione di app che contiene una chiave di accesso per l'argomento personalizzato. |
Gli esempi seguenti illustrano i dati di associazione di output di Griglia di eventi nel file function.json.
{
"type": "eventGrid",
"name": "outputEvent",
"topicEndpointUri": "MyEventGridTopicUriSetting",
"topicKeySetting": "MyEventGridTopicKeySetting",
"direction": "out"
}
Ecco il codice script C# che crea un evento:
#r "Microsoft.Azure.EventGrid"
using System;
using Microsoft.Azure.EventGrid.Models;
using Microsoft.Extensions.Logging;
public static void Run(TimerInfo myTimer, out EventGridEvent outputEvent, ILogger log)
{
outputEvent = new EventGridEvent("message-id", "subject-name", "event-data", "event-type", DateTime.UtcNow, "1.0");
}
Ecco il codice script C# che crea più eventi:
#r "Microsoft.Azure.EventGrid"
using System;
using Microsoft.Azure.EventGrid.Models;
using Microsoft.Extensions.Logging;
public static void Run(TimerInfo myTimer, ICollector<EventGridEvent> outputEvent, ILogger log)
{
outputEvent.Add(new EventGridEvent("message-id-1", "subject-name", "event-data", "event-type", DateTime.UtcNow, "1.0"));
outputEvent.Add(new EventGridEvent("message-id-2", "subject-name", "event-data", "event-type", DateTime.UtcNow, "1.0"));
}
Trigger per bus di servizio
Nella tabella seguente sono illustrate le proprietà di configurazione dell'associazione impostate nel file function.json.
Proprietà di function.json | Descrizione |
---|---|
type | Deve essere impostato su serviceBusTrigger . Questa proprietà viene impostata automaticamente quando si crea il trigger nel portale di Azure. |
direction | Deve essere impostato su in . Questa proprietà viene impostata automaticamente quando si crea il trigger nel portale di Azure. |
name | Nome della variabile che rappresenta il messaggio della coda o dell'argomento nel codice della funzione. |
queueName | Nome della coda da monitorare. Impostare questa proprietà solo quando si monitora una coda, non un argomento. |
topicName | Nome dell'argomento da monitorare. Impostare questa proprietà solo quando si monitora un argomento, non una coda. |
subscriptionName | Nome della sottoscrizione da monitorare. Impostare questa proprietà solo quando si monitora un argomento, non una coda. |
connection | Nome di un'impostazione o di una raccolta di impostazioni dell'app che specifica come connettersi ai Bus di servizio. Vedere Connessioni. |
accessRights | Diritti di accesso per la stringa di connessione. I valori disponibili sono manage e listen . Il valore predefinito è manage , che indica che connection dispone dell'autorizzazione Gestisci. Se si usa una stringa di connessione priva dell'autorizzazione Gestisci, impostare accessRights su "listen". In caso contrario, il runtime di Funzioni potrebbe non riuscire a eseguire operazioni che richiedono diritti di gestione. In Funzioni di Azure versione 2.x e successive questa proprietà non è disponibile perché la versione più recente di Bus di servizio SDK non supporta le operazioni di gestione. |
isSessionsEnabled | true se ci si connette a una coda o sottoscrizione session-aware. false in caso contrario, ovvero il valore predefinito. |
Completamento automatico | true quando il trigger deve chiamare automaticamente il completamento dopo l'elaborazione o se il codice della funzione chiamerà manualmente il completamento.L'impostazione su false è supportata solo in C#.Se impostato su true , il trigger completa automaticamente il messaggio se l'esecuzione della funzione viene completata correttamente e abbandona il messaggio in caso contrario.<br/Quando è impostato su false , l'utente è responsabile della chiamata dei metodi ServiceBusReceiver per completare, abbandonare o disattivare il messaggio, la sessione o il batch. Quando viene generata un'eccezione (e non viene chiamato nessuno dei metodi ServiceBusReceiver ), il blocco rimane. Una volta scaduto il blocco, il messaggio viene nuovamente accodato con l'incremento DeliveryCount e il blocco viene rinnovato automaticamente.Questa proprietà è disponibile solo in Funzioni di Azure 2.x e versioni successive. |
L'esempio seguente mostra un'associazione di trigger del bus di servizio in un file function.json e una funzione script C# che usa l'associazione. La funzione legge i metadati del messaggio e registra un messaggio della coda del bus di servizio.
Ecco i dati di associazione nel file function.json:
{
"bindings": [
{
"queueName": "testqueue",
"connection": "MyServiceBusConnection",
"name": "myQueueItem",
"type": "serviceBusTrigger",
"direction": "in"
}
],
"disabled": false
}
Ecco il codice script C#:
using System;
public static void Run(string myQueueItem,
Int32 deliveryCount,
DateTime enqueuedTimeUtc,
string messageId,
TraceWriter log)
{
log.Info($"C# ServiceBus queue trigger function processed message: {myQueueItem}");
log.Info($"EnqueuedTimeUtc={enqueuedTimeUtc}");
log.Info($"DeliveryCount={deliveryCount}");
log.Info($"MessageId={messageId}");
}
Output del bus di servizio
Nella tabella seguente sono illustrate le proprietà di configurazione dell'associazione impostate nel file function.json.
Proprietà di function.json | Descrizione |
---|---|
type | Deve essere impostato su serviceBus . Questa proprietà viene impostata automaticamente quando si crea il trigger nel portale di Azure. |
direction | Deve essere impostato su out . Questa proprietà viene impostata automaticamente quando si crea il trigger nel portale di Azure. |
name | Nome della variabile che rappresenta il messaggio della coda o dell'argomento nel codice della funzione. Impostare su "$return" per fare riferimento al valore restituito della funzione. |
queueName | Nome della coda. Impostare questa proprietà solo se si inviano messaggi della coda, non dell'argomento. |
topicName | Nome dell'argomento. Impostare questa proprietà solo se si inviano messaggi dell'argomento, non della coda. |
connection | Nome di un'impostazione o di una raccolta di impostazioni dell'app che specifica come connettersi ai Bus di servizio. Vedere Connessioni. |
accessRights (solo v1) | Diritti di accesso per la stringa di connessione. I valori disponibili sono manage e listen . Il valore predefinito è manage , che indica che connection dispone dell'autorizzazione Gestisci. Se si usa una stringa di connessione priva dell'autorizzazione Gestisci, impostare accessRights su "listen". In caso contrario, il runtime di Funzioni potrebbe non riuscire a eseguire operazioni che richiedono diritti di gestione. In Funzioni di Azure versione 2.x e successive questa proprietà non è disponibile perché la versione più recente di Bus di servizio SDK non supporta le operazioni di gestione. |
L'esempio seguente mostra un'associazione di output del bus di servizio in un file function.json e una funzione script C# che usa l'associazione. La funzione usa un trigger timer per inviare un messaggio della coda ogni 15 secondi.
Ecco i dati di associazione nel file function.json:
{
"bindings": [
{
"schedule": "0/15 * * * * *",
"name": "myTimer",
"runsOnStartup": true,
"type": "timerTrigger",
"direction": "in"
},
{
"name": "outputSbQueue",
"type": "serviceBus",
"queueName": "testqueue",
"connection": "MyServiceBusConnection",
"direction": "out"
}
],
"disabled": false
}
Ecco il codice script C# che crea un singolo messaggio:
public static void Run(TimerInfo myTimer, ILogger log, out string outputSbQueue)
{
string message = $"Service Bus queue message created at: {DateTime.Now}";
log.LogInformation(message);
outputSbQueue = message;
}
Ecco il codice script C# che crea più messaggi:
public static async Task Run(TimerInfo myTimer, ILogger log, IAsyncCollector<string> outputSbQueue)
{
string message = $"Service Bus queue messages created at: {DateTime.Now}";
log.LogInformation(message);
await outputSbQueue.AddAsync("1 " + message);
await outputSbQueue.AddAsync("2 " + message);
}
Trigger di Azure Cosmos DB v2
Questa sezione descrive esclusivamente il supporto per la versione 4.x+ dell'estensione .
Nella tabella seguente sono illustrate le proprietà di configurazione dell'associazione impostate nel file function.json.
Proprietà di function.json | Descrizione |
---|---|
type | Deve essere impostato su cosmosDBTrigger . |
direction | Deve essere impostato su in . Questo parametro viene impostato automaticamente quando si crea il trigger nel portale di Azure. |
name | Il nome della variabile usato nel codice funzione che rappresenta l'elenco di documenti con le modifiche. |
connection | Nome di un'impostazione o di una raccolta di impostazioni dell'app che specifica come connettersi all'account Azure Cosmos DB monitorato. Per altre informazioni, vedere Connections. |
databaseName | Il nome del database di Azure Cosmos DB con il contenitore monitorato. |
containerName | Nome del contenitore monitorato. |
leaseConnection | (Facoltativo) Nome di un'impostazione o di un contenitore di impostazioni dell'app che specifica come connettersi all'account Azure Cosmos DB che contiene il contenitore di lease. Se non impostato, viene usato il valore connection . Questo parametro viene impostato automaticamente al momento della creazione dell'associazione nel portale. La stringa di connessione per il contenitore di lease deve disporre di autorizzazioni di scrittura. |
leaseDatabaseName | (Facoltativo) Il nome del database in cui si trova il contenitore usato per archiviare i lease. Se non impostato, viene usato il valore dell'impostazione databaseName . |
leaseContainerName | (Facoltativo) Nome del contenitore usato per archiviare i lease. Se non impostato, viene usato il valore leases . |
createLeaseContainerIfNotExists | (Facoltativo) Se impostato su true , il contenitore lease viene creato automaticamente se non è già esistente. Il valore predefinito è false . Quando si usano identità di Microsoft Entra se si imposta il valore su true , la creazione di contenitori non è un’operazione consentita e la funzione non potrà essere avviata. |
leasesContainerThroughput | (Facoltativo) Definisce il numero di unità richiesta da assegnare quando viene creato il contenitore lease. Questa impostazione viene usata solo quando createLeaseContainerIfNotExists è impostato su true . Questo parametro viene impostato automaticamente al momento della creazione dell'associazione tramite il portale. |
leaseContainerPrefix | (Facoltativo) Se impostato, il valore viene aggiunto come prefisso ai lease creati nel contenitore Lease per questa funzione. L'uso di un prefisso consente a due funzioni di Azure diverse di condividere lo stesso contenitore lease usando prefissi diversi. |
feedPollDelay | (Facoltativo) Il tempo (in millisecondi) per il ritardo tra il polling di una partizione alla ricerca di nuove modifiche al feed, dopo la rimozione di tutte le modifiche correnti. L'impostazione predefinita è 5,000 millisecondi (o 5 secondi). |
leaseAcquireInterval | (Facoltativo) Se impostato, definisce, in millisecondi, l'intervallo per l'avvio di un'attività che consente di calcolare se le partizioni sono distribuite equamente tra le istanze di host note. Il valore predefinito è 13000 (13 secondi). |
leaseExpirationInterval | (Facoltativo) Se impostato, definisce, in millisecondi, l'intervallo che indica la durata di un lease su un lease che rappresenta una partizione. Se il lease non viene rinnovato entro questo intervallo, ne comporterà la scadenza e la proprietà della partizione passerà a un'altra istanza. Il valore predefinito è 60000 (60 secondi). |
leaseRenewInterval | (Facoltativo) Se impostato, definisce, in millisecondi, l'intervallo di rinnovo per tutti i lease per le partizioni attualmente occupate da un'istanza. Il valore predefinito è 17000 (17 secondi). |
maxItemsPerInvocation | (Facoltativo) Se impostata, questa proprietà imposta il numero massimo di elementi ricevuti per Chiamata di funzione. Se le operazioni nel contenitore monitorato vengono eseguite tramite stored procedure, l'ambito della transazione viene mantenuto durante la lettura degli elementi dal feed di modifiche. Di conseguenza, il numero di elementi ricevuti potrebbe essere superiore al valore specificato in modo che gli elementi modificati dalla stessa transazione vengano restituiti come parte di un batch atomico. |
startFromBeginning | (Facoltativo) Questa opzione indica al trigger di leggere le modifiche dall'inizio della cronologia delle modifiche del contenitore anziché a partire dall'ora corrente. La lettura dall’inizio funziona solo al primo avvio del trigger, perché per le esecuzioni successive i checkpoint sono già archiviati. L'impostazione di questa opzione su true in presenza di lease già creati non ha alcun effetto. |
startFromTime | (Facoltativo) Ottiene o imposta la data e l'ora da cui inizializzare l'operazione di lettura del feed di modifiche. Il formato consigliato è ISO 8601 con l'identificatore UTC, ad esempio 2021-02-16T14:19:29Z . Viene usato solo per impostare lo stato del trigger iniziale. Dopo che il trigger ha uno stato di lease, la modifica di questo valore non ha alcun effetto. |
preferredLocations | (Facoltativo) Definisce le posizioni preferite (aree) per gli account di database con replica geografica nel servizio Azure Cosmos DB. I valori devono essere delimitati da virgole. Ad esempio, "Stati Uniti orientali, Stati Uniti centro-meridionali, Europa settentrionale". |
L'esempio seguente mostra un'associazione di trigger di Azure Cosmos DB in un file function.json e una funzione script C# che usa l'associazione. La funzione scrive messaggi di log quando i record di Azure Cosmos DB vengono aggiunti o modificati.
Ecco i dati di associazione nel file function.json:
{
"type": "cosmosDBTrigger",
"name": "documents",
"direction": "in",
"leaseContainerName": "leases",
"connection": "<connection-app-setting>",
"databaseName": "Tasks",
"containerName": "Items",
"createLeaseContainerIfNotExists": true
}
Ecco il codice script C#:
using System;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
// Customize the model with your own desired properties
public class ToDoItem
{
public string id { get; set; }
public string Description { get; set; }
}
public static void Run(IReadOnlyList<ToDoItem> documents, ILogger log)
{
log.LogInformation("Documents modified " + documents.Count);
log.LogInformation("First document Id " + documents[0].id);
}
Input di Azure Cosmos DB v2
Questa sezione descrive esclusivamente il supporto per la versione 4.x+ dell'estensione .
Nella tabella seguente sono illustrate le proprietà di configurazione dell'associazione impostate nel file function.json.
Proprietà di function.json | Descrizione |
---|---|
type | Deve essere impostato su cosmosDB . |
direction | Deve essere impostato su in . |
name | Il nome della variabile usato nel codice funzione che rappresenta l'elenco di documenti con le modifiche. |
connection | Nome di un'impostazione o di un contenitore di impostazioni dell'app che specifica come connettersi all'account Azure Cosmos DB monitorato. Per altre informazioni, vedere Connections. |
databaseName | Il nome del database di Azure Cosmos DB con il contenitore monitorato. |
containerName | Nome del contenitore monitorato. |
partitionKey | Specifica il valore della chiave di partizione per la ricerca. Può includere i parametri di associazione. È necessario per le ricerche nei contenitori partizionati. |
id | ID del documento da recuperare. Questa proprietà supporta le espressioni di associazione. Non impostare entrambe le proprietà id e sqlQuery . Se non si imposta una delle due proprietà, verrà recuperato l'intero contenitore. |
sqlQuery | Query SQL di Azure Cosmos DB usata per recuperare più documenti. La proprietà supporta le associazioni del runtime, come nell'esempio seguente: SELECT * FROM c where c.departmentId = {departmentId} . Non impostare entrambe le proprietà id e sqlQuery . Se non si imposta una delle due proprietà, verrà recuperato l'intero contenitore. |
preferredLocations | (Facoltativo) Definisce le posizioni preferite (aree) per gli account di database con replica geografica nel servizio Azure Cosmos DB. I valori devono essere delimitati da virgole. Ad esempio: East US,South Central US,North Europe . |
Questa sezione contiene gli esempi seguenti:
- Trigger della coda e ricerca dell'ID dalla stringa
- Trigger della coda e recupero di più documenti con SqlQuery
- Trigger HTTP e ricerca dell'ID da una stringa di query
- Trigger HTTP e ricerca dell'ID dai dati della route
- Trigger HTTP e recupero di più documenti con SqlQuery
- Trigger HTTP e recupero di più documenti con DocumentClient
Gli esempi di trigger HTTP fanno riferimento a un tipo ToDoItem
semplice:
namespace CosmosDBSamplesV2
{
public class ToDoItem
{
public string Id { get; set; }
public string Description { get; set; }
}
}
Trigger della coda e ricerca dell'ID dalla stringa
L'esempio seguente mostra un'associazione di input di Azure Cosmos DB in un file function.json e una funzione script C# che usa l'associazione. La funzione legge un singolo documento e aggiorna il relativo valore di testo.
Ecco i dati di associazione nel file function.json:
{
"name": "inputDocument",
"type": "cosmosDB",
"databaseName": "MyDatabase",
"collectionName": "MyCollection",
"id" : "{queueTrigger}",
"partitionKey": "{partition key value}",
"connectionStringSetting": "MyAccount_COSMOSDB",
"direction": "in"
}
Ecco il codice script C#:
using System;
// Change input document contents using Azure Cosmos DB input binding
public static void Run(string myQueueItem, dynamic inputDocument)
{
inputDocument.text = "This has changed.";
}
Trigger della coda e recupero di più documenti con SqlQuery
L'esempio seguente mostra un'associazione di input di Azure Cosmos DB in un file function.json e una funzione script C# che usa l'associazione. La funzione recupera più documenti specificati da una query SQL mediante un trigger di coda per personalizzare i parametri di query.
Il trigger di coda fornisce un parametro departmentId
. Un messaggio nella coda di { "departmentId" : "Finance" }
restituirà tutti i record per il reparto finanziario.
Ecco i dati di associazione nel file function.json:
{
"name": "documents",
"type": "cosmosDB",
"direction": "in",
"databaseName": "MyDb",
"collectionName": "MyCollection",
"sqlQuery": "SELECT * from c where c.departmentId = {departmentId}",
"connectionStringSetting": "CosmosDBConnection"
}
Ecco il codice script C#:
public static void Run(QueuePayload myQueueItem, IEnumerable<dynamic> documents)
{
foreach (var doc in documents)
{
// operate on each document
}
}
public class QueuePayload
{
public string departmentId { get; set; }
}
Trigger HTTP e ricerca dell'ID da una stringa di query
L'esempio seguente illustra una funzione script C# che recupera un singolo documento. La funzione viene attivata da una richiesta HTTP che usa una stringa di query per specificare l'ID e il valore della chiave di partizione da cercare. Questo ID e il valore della chiave di partizione sono usati per recuperare un documento ToDoItem
dal database e dalla raccolta specificati.
Ecco il file function.json:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"type": "cosmosDB",
"name": "toDoItem",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connectionStringSetting": "CosmosDBConnection",
"direction": "in",
"Id": "{Query.id}",
"PartitionKey" : "{Query.partitionKeyValue}"
}
],
"disabled": false
}
Ecco il codice script C#:
using System.Net;
using Microsoft.Extensions.Logging;
public static HttpResponseMessage Run(HttpRequestMessage req, ToDoItem toDoItem, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
if (toDoItem == null)
{
log.LogInformation($"ToDo item not found");
}
else
{
log.LogInformation($"Found ToDo item, Description={toDoItem.Description}");
}
return req.CreateResponse(HttpStatusCode.OK);
}
Trigger HTTP e ricerca dell'ID dai dati della route
L'esempio seguente illustra una funzione script C# che recupera un singolo documento. La funzione viene attivata da una richiesta HTTP che usa i dati della route per specificare l'ID e il valore della chiave di partizione da cercare. Questo ID e il valore della chiave di partizione sono usati per recuperare un documento ToDoItem
dal database e dalla raccolta specificati.
Ecco il file function.json:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
],
"route":"todoitems/{partitionKeyValue}/{id}"
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"type": "cosmosDB",
"name": "toDoItem",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connectionStringSetting": "CosmosDBConnection",
"direction": "in",
"id": "{id}",
"partitionKey": "{partitionKeyValue}"
}
],
"disabled": false
}
Ecco il codice script C#:
using System.Net;
using Microsoft.Extensions.Logging;
public static HttpResponseMessage Run(HttpRequestMessage req, ToDoItem toDoItem, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
if (toDoItem == null)
{
log.LogInformation($"ToDo item not found");
}
else
{
log.LogInformation($"Found ToDo item, Description={toDoItem.Description}");
}
return req.CreateResponse(HttpStatusCode.OK);
}
Trigger HTTP e recupero di più documenti con SqlQuery
L'esempio seguente illustra una funzione script C# che recupera un elenco di documenti. La funzione viene attivata da una richiesta HTTP. La query è specificata nella proprietà dell'attributo SqlQuery
.
Ecco il file function.json:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"type": "cosmosDB",
"name": "toDoItems",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connectionStringSetting": "CosmosDBConnection",
"direction": "in",
"sqlQuery": "SELECT top 2 * FROM c order by c._ts desc"
}
],
"disabled": false
}
Ecco il codice script C#:
using System.Net;
using Microsoft.Extensions.Logging;
public static HttpResponseMessage Run(HttpRequestMessage req, IEnumerable<ToDoItem> toDoItems, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
foreach (ToDoItem toDoItem in toDoItems)
{
log.LogInformation(toDoItem.Description);
}
return req.CreateResponse(HttpStatusCode.OK);
}
Trigger HTTP e recupero di più documenti con DocumentClient
L'esempio seguente illustra una funzione script C# che recupera un elenco di documenti. La funzione viene attivata da una richiesta HTTP. Il codice usa un'istanza di DocumentClient
fornita dall'associazione di Azure Cosmos DB per leggere un elenco di documenti. L'istanza di DocumentClient
potrebbe essere usata anche per operazioni di scrittura.
Ecco il file function.json:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"type": "cosmosDB",
"name": "client",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connectionStringSetting": "CosmosDBConnection",
"direction": "inout"
}
],
"disabled": false
}
Ecco il codice script C#:
#r "Microsoft.Azure.Documents.Client"
using System.Net;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Microsoft.Extensions.Logging;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, DocumentClient client, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
Uri collectionUri = UriFactory.CreateDocumentCollectionUri("ToDoItems", "Items");
string searchterm = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "searchterm", true) == 0)
.Value;
if (searchterm == null)
{
return req.CreateResponse(HttpStatusCode.NotFound);
}
log.LogInformation($"Searching for word: {searchterm} using Uri: {collectionUri.ToString()}");
IDocumentQuery<ToDoItem> query = client.CreateDocumentQuery<ToDoItem>(collectionUri)
.Where(p => p.Description.Contains(searchterm))
.AsDocumentQuery();
while (query.HasMoreResults)
{
foreach (ToDoItem result in await query.ExecuteNextAsync())
{
log.LogInformation(result.Description);
}
}
return req.CreateResponse(HttpStatusCode.OK);
}
Output di Azure Cosmos DB v2
Questa sezione descrive esclusivamente il supporto per la versione 4.x+ dell'estensione .
Nella tabella seguente sono illustrate le proprietà di configurazione dell'associazione impostate nel file function.json.
Proprietà di function.json | Descrizione |
---|---|
connection | Nome di un'impostazione o di una raccolta di impostazioni dell'app che specifica come connettersi all'account Azure Cosmos DB monitorato. Per altre informazioni, vedere Connections. |
databaseName | Il nome del database di Azure Cosmos DB con il contenitore monitorato. |
containerName | Nome del contenitore monitorato. |
createIfNotExists | Valore booleano che indica se il contenitore viene creato quando non esiste. Il valore predefinito è false perché i nuovi contenitori vengono creati con una velocità effettiva riservata, che ha implicazioni in termini di costi. Per ulteriori informazioni, vedere la pagina dei prezzi. |
partitionKey | Quando createIfNotExists è true, definisce il percorso della chiave di partizione per il contenitore creato. Può includere i parametri di associazione. |
containerThroughput | Se createIfNotExists è true, definisce la velocità effettiva del contenitore creato. |
preferredLocations | (Facoltativo) Definisce le posizioni preferite (aree) per gli account di database con replica geografica nel servizio Azure Cosmos DB. I valori devono essere delimitati da virgole. Ad esempio: East US,South Central US,North Europe . |
Questa sezione contiene gli esempi seguenti:
- Trigger della coda e scrittura di un documento
- Trigger della coda e scrittura di documenti con IAsyncCollector
Trigger della coda e scrittura di un documento
L'esempio seguente mostra un'associazione di output di Azure Cosmos DB in un file function.json e una funzione script C# che usa l'associazione. La funzione usa un'associazione di input di coda per una coda che riceve JSON nel formato seguente:
{
"name": "John Henry",
"employeeId": "123456",
"address": "A town nearby"
}
La funzione crea documenti di Azure Cosmos DB nel formato seguente per ogni record:
{
"id": "John Henry-123456",
"name": "John Henry",
"employeeId": "123456",
"address": "A town nearby"
}
Ecco i dati di associazione nel file function.json:
{
"name": "employeeDocument",
"type": "cosmosDB",
"databaseName": "MyDatabase",
"collectionName": "MyCollection",
"createIfNotExists": true,
"connectionStringSetting": "MyAccount_COSMOSDB",
"direction": "out"
}
Ecco il codice script C#:
#r "Newtonsoft.Json"
using Microsoft.Azure.WebJobs.Host;
using Newtonsoft.Json.Linq;
using Microsoft.Extensions.Logging;
public static void Run(string myQueueItem, out object employeeDocument, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
dynamic employee = JObject.Parse(myQueueItem);
employeeDocument = new {
id = employee.name + "-" + employee.employeeId,
name = employee.name,
employeeId = employee.employeeId,
address = employee.address
};
}
Trigger della coda e scrittura di documenti con IAsyncCollector
Per creare più documenti, è possibile definire l'associazione a ICollector<T>
o IAsyncCollector<T>
dove T
è uno dei tipi supportati.
Questo esempio si riferisce a un tipo ToDoItem
semplice:
namespace CosmosDBSamplesV2
{
public class ToDoItem
{
public string id { get; set; }
public string Description { get; set; }
}
}
Ecco il file function.json:
{
"bindings": [
{
"name": "toDoItemsIn",
"type": "queueTrigger",
"direction": "in",
"queueName": "todoqueueforwritemulti",
"connectionStringSetting": "AzureWebJobsStorage"
},
{
"type": "cosmosDB",
"name": "toDoItemsOut",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connectionStringSetting": "CosmosDBConnection",
"direction": "out"
}
],
"disabled": false
}
Ecco il codice script C#:
using System;
using Microsoft.Extensions.Logging;
public static async Task Run(ToDoItem[] toDoItemsIn, IAsyncCollector<ToDoItem> toDoItemsOut, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed {toDoItemsIn?.Length} items");
foreach (ToDoItem toDoItem in toDoItemsIn)
{
log.LogInformation($"Description={toDoItem.Description}");
await toDoItemsOut.AddAsync(toDoItem);
}
}
Trigger di Azure Cosmos DB v1
L'esempio seguente mostra un'associazione di trigger di Azure Cosmos DB in un file function.json e una funzione script C# che usa l'associazione. La funzione scrive i messaggi di log quando vengono modificati i record di Azure Cosmos DB.
Ecco i dati di associazione nel file function.json:
{
"type": "cosmosDBTrigger",
"name": "documents",
"direction": "in",
"leaseCollectionName": "leases",
"connectionStringSetting": "<connection-app-setting>",
"databaseName": "Tasks",
"collectionName": "Items",
"createLeaseCollectionIfNotExists": true
}
Ecco il codice script C#:
#r "Microsoft.Azure.Documents.Client"
using System;
using Microsoft.Azure.Documents;
using System.Collections.Generic;
public static void Run(IReadOnlyList<Document> documents, TraceWriter log)
{
log.Info("Documents modified " + documents.Count);
log.Info("First document Id " + documents[0].Id);
}
Input di Azure Cosmos DB v1
Questa sezione contiene gli esempi seguenti:
- Trigger della coda e ricerca dell'ID dalla stringa
- Trigger della coda e recupero di più documenti con SqlQuery
- Trigger HTTP e ricerca dell'ID da una stringa di query
- Trigger HTTP e ricerca dell'ID dai dati della route
- Trigger HTTP e recupero di più documenti con SqlQuery
- Trigger HTTP e recupero di più documenti con DocumentClient
Gli esempi di trigger HTTP fanno riferimento a un tipo ToDoItem
semplice:
namespace CosmosDBSamplesV1
{
public class ToDoItem
{
public string Id { get; set; }
public string Description { get; set; }
}
}
Trigger della coda e ricerca dell'ID dalla stringa
L'esempio seguente mostra un'associazione di input di Azure Cosmos DB in un file function.json e una funzione script C# che usa l'associazione. La funzione legge un singolo documento e aggiorna il relativo valore di testo.
Ecco i dati di associazione nel file function.json:
{
"name": "inputDocument",
"type": "documentDB",
"databaseName": "MyDatabase",
"collectionName": "MyCollection",
"id" : "{queueTrigger}",
"partitionKey": "{partition key value}",
"connection": "MyAccount_COSMOSDB",
"direction": "in"
}
Ecco il codice script C#:
using System;
// Change input document contents using Azure Cosmos DB input binding
public static void Run(string myQueueItem, dynamic inputDocument)
{
inputDocument.text = "This has changed.";
}
Trigger della coda e recupero di più documenti con SqlQuery
L'esempio seguente mostra un'associazione di input di Azure Cosmos DB in un file function.json e una funzione script C# che usa l'associazione. La funzione recupera più documenti specificati da una query SQL mediante un trigger di coda per personalizzare i parametri di query.
Il trigger di coda fornisce un parametro departmentId
. Un messaggio nella coda di { "departmentId" : "Finance" }
restituirà tutti i record per il reparto finanziario.
Ecco i dati di associazione nel file function.json:
{
"name": "documents",
"type": "documentdb",
"direction": "in",
"databaseName": "MyDb",
"collectionName": "MyCollection",
"sqlQuery": "SELECT * from c where c.departmentId = {departmentId}",
"connection": "CosmosDBConnection"
}
Ecco il codice script C#:
public static void Run(QueuePayload myQueueItem, IEnumerable<dynamic> documents)
{
foreach (var doc in documents)
{
// operate on each document
}
}
public class QueuePayload
{
public string departmentId { get; set; }
}
Trigger HTTP e ricerca dell'ID da una stringa di query
L'esempio seguente illustra una funzione script C# che recupera un singolo documento. La funzione viene attivata da una richiesta HTTP che usa una stringa di query per specificare l'ID da cercare. Questo ID viene usato per recuperare un documento ToDoItem
dal database e dalla raccolta specificati.
Ecco il file function.json:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"type": "documentDB",
"name": "toDoItem",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connection": "CosmosDBConnection",
"direction": "in",
"Id": "{Query.id}"
}
],
"disabled": true
}
Ecco il codice script C#:
using System.Net;
public static HttpResponseMessage Run(HttpRequestMessage req, ToDoItem toDoItem, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
if (toDoItem == null)
{
log.Info($"ToDo item not found");
}
else
{
log.Info($"Found ToDo item, Description={toDoItem.Description}");
}
return req.CreateResponse(HttpStatusCode.OK);
}
Trigger HTTP e ricerca dell'ID dai dati della route
L'esempio seguente illustra una funzione script C# che recupera un singolo documento. La funzione viene attivata da una richiesta HTTP che usa i dati della route per specificare l'ID da cercare. Questo ID viene usato per recuperare un documento ToDoItem
dal database e dalla raccolta specificati.
Ecco il file function.json:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
],
"route":"todoitems/{id}"
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"type": "documentDB",
"name": "toDoItem",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connection": "CosmosDBConnection",
"direction": "in",
"Id": "{id}"
}
],
"disabled": false
}
Ecco il codice script C#:
using System.Net;
public static HttpResponseMessage Run(HttpRequestMessage req, ToDoItem toDoItem, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
if (toDoItem == null)
{
log.Info($"ToDo item not found");
}
else
{
log.Info($"Found ToDo item, Description={toDoItem.Description}");
}
return req.CreateResponse(HttpStatusCode.OK);
}
Trigger HTTP e recupero di più documenti con SqlQuery
L'esempio seguente illustra una funzione script C# che recupera un elenco di documenti. La funzione viene attivata da una richiesta HTTP. La query è specificata nella proprietà dell'attributo SqlQuery
.
Ecco il file function.json:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"type": "documentDB",
"name": "toDoItems",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connection": "CosmosDBConnection",
"direction": "in",
"sqlQuery": "SELECT top 2 * FROM c order by c._ts desc"
}
],
"disabled": false
}
Ecco il codice script C#:
using System.Net;
public static HttpResponseMessage Run(HttpRequestMessage req, IEnumerable<ToDoItem> toDoItems, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
foreach (ToDoItem toDoItem in toDoItems)
{
log.Info(toDoItem.Description);
}
return req.CreateResponse(HttpStatusCode.OK);
}
Trigger HTTP e recupero di più documenti con DocumentClient
L'esempio seguente illustra una funzione script C# che recupera un elenco di documenti. La funzione viene attivata da una richiesta HTTP. Il codice usa un'istanza di DocumentClient
fornita dall'associazione di Azure Cosmos DB per leggere un elenco di documenti. L'istanza di DocumentClient
potrebbe essere usata anche per operazioni di scrittura.
Ecco il file function.json:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"type": "documentDB",
"name": "client",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connection": "CosmosDBConnection",
"direction": "inout"
}
],
"disabled": false
}
Ecco il codice script C#:
#r "Microsoft.Azure.Documents.Client"
using System.Net;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, DocumentClient client, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
Uri collectionUri = UriFactory.CreateDocumentCollectionUri("ToDoItems", "Items");
string searchterm = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "searchterm", true) == 0)
.Value;
if (searchterm == null)
{
return req.CreateResponse(HttpStatusCode.NotFound);
}
log.Info($"Searching for word: {searchterm} using Uri: {collectionUri.ToString()}");
IDocumentQuery<ToDoItem> query = client.CreateDocumentQuery<ToDoItem>(collectionUri)
.Where(p => p.Description.Contains(searchterm))
.AsDocumentQuery();
while (query.HasMoreResults)
{
foreach (ToDoItem result in await query.ExecuteNextAsync())
{
log.Info(result.Description);
}
}
return req.CreateResponse(HttpStatusCode.OK);
}
Output di Azure Cosmos DB v1
Questa sezione contiene gli esempi seguenti:
- Trigger della coda e scrittura di un documento
- Trigger della coda, scrittura di documenti con
IAsyncCollector
Trigger della coda e scrittura di un documento
L'esempio seguente mostra un'associazione di output di Azure Cosmos DB in un file function.json e una funzione script C# che usa l'associazione. La funzione usa un'associazione di input di coda per una coda che riceve JSON nel formato seguente:
{
"name": "John Henry",
"employeeId": "123456",
"address": "A town nearby"
}
La funzione crea documenti di Azure Cosmos DB nel formato seguente per ogni record:
{
"id": "John Henry-123456",
"name": "John Henry",
"employeeId": "123456",
"address": "A town nearby"
}
Ecco i dati di associazione nel file function.json:
{
"name": "employeeDocument",
"type": "documentDB",
"databaseName": "MyDatabase",
"collectionName": "MyCollection",
"createIfNotExists": true,
"connection": "MyAccount_COSMOSDB",
"direction": "out"
}
Ecco il codice script C#:
#r "Newtonsoft.Json"
using Microsoft.Azure.WebJobs.Host;
using Newtonsoft.Json.Linq;
public static void Run(string myQueueItem, out object employeeDocument, TraceWriter log)
{
log.Info($"C# Queue trigger function processed: {myQueueItem}");
dynamic employee = JObject.Parse(myQueueItem);
employeeDocument = new {
id = employee.name + "-" + employee.employeeId,
name = employee.name,
employeeId = employee.employeeId,
address = employee.address
};
}
Trigger della coda e scrittura di documenti con IAsyncCollector
Per creare più documenti, è possibile definire l'associazione a ICollector<T>
o IAsyncCollector<T>
dove T
è uno dei tipi supportati.
Questo esempio si riferisce a un tipo ToDoItem
semplice:
namespace CosmosDBSamplesV1
{
public class ToDoItem
{
public string Id { get; set; }
public string Description { get; set; }
}
}
Ecco il file function.json:
{
"bindings": [
{
"name": "toDoItemsIn",
"type": "queueTrigger",
"direction": "in",
"queueName": "todoqueueforwritemulti",
"connection": "AzureWebJobsStorage"
},
{
"type": "documentDB",
"name": "toDoItemsOut",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connection": "CosmosDBConnection",
"direction": "out"
}
],
"disabled": false
}
Ecco il codice script C#:
using System;
public static async Task Run(ToDoItem[] toDoItemsIn, IAsyncCollector<ToDoItem> toDoItemsOut, TraceWriter log)
{
log.Info($"C# Queue trigger function processed {toDoItemsIn?.Length} items");
foreach (ToDoItem toDoItem in toDoItemsIn)
{
log.Info($"Description={toDoItem.Description}");
await toDoItemsOut.AddAsync(toDoItem);
}
}
Trigger SQL di Azure
Altri esempi per il trigger Azure SQL sono disponibili nel repository GitHub.
L’esempio fa riferimento a una classe ToDoItem
e a una tabella di database corrispondente:
namespace AzureSQL.ToDo
{
public class ToDoItem
{
public Guid Id { get; set; }
public int? order { get; set; }
public string title { get; set; }
public string url { get; set; }
public bool? completed { get; set; }
}
}
CREATE TABLE dbo.ToDo (
[Id] UNIQUEIDENTIFIER PRIMARY KEY,
[order] INT NULL,
[title] NVARCHAR(200) NOT NULL,
[url] NVARCHAR(200) NOT NULL,
[completed] BIT NOT NULL
);
Il rilevamento delle modifiche è abilitato nel database e nella tabella:
ALTER DATABASE [SampleDatabase]
SET CHANGE_TRACKING = ON
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON);
ALTER TABLE [dbo].[ToDo]
ENABLE CHANGE_TRACKING;
Il trigger SQL viene associato a un IReadOnlyList<SqlChange<T>>
, un elenco di oggetti SqlChange
, ognuno con due proprietà:
- Elemento: l'elemento modificato. Il tipo dell'elemento deve seguire lo schema della tabella come illustrato nella classe
ToDoItem
. - Operazione: valore di enumerazione
SqlChangeOperation
. I valori possibili sonoInsert
,Update
eDelete
.
L'esempio seguente mostra un trigger SQL in un file function.json e una funzione script C# richiamata quando sono presenti modifiche alla tabella ToDo
:
Di seguito sono riportati i dati di associazione nel file function.json:
{
"name": "todoChanges",
"type": "sqlTrigger",
"direction": "in",
"tableName": "dbo.ToDo",
"connectionStringSetting": "SqlConnectionString"
}
Di seguito è riportata la funzione script C#:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
public static void Run(IReadOnlyList<SqlChange<ToDoItem>> todoChanges, ILogger log)
{
log.LogInformation($"C# SQL trigger function processed a request.");
foreach (SqlChange<ToDoItem> change in todoChanges)
{
ToDoItem toDoItem = change.Item;
log.LogInformation($"Change operation: {change.Operation}");
log.LogInformation($"Id: {toDoItem.Id}, Title: {toDoItem.title}, Url: {toDoItem.url}, Completed: {toDoItem.completed}");
}
}
Input SQL di Azure
Altri esempi per l'associazione dell’input Azure SQL sono disponibili nel repository GitHub.
Questa sezione contiene gli esempi seguenti:
Gli esempi fanno riferimento a una classe ToDoItem
e a una tabella di database corrispondente:
namespace AzureSQL.ToDo
{
public class ToDoItem
{
public Guid Id { get; set; }
public int? order { get; set; }
public string title { get; set; }
public string url { get; set; }
public bool? completed { get; set; }
}
}
CREATE TABLE dbo.ToDo (
[Id] UNIQUEIDENTIFIER PRIMARY KEY,
[order] INT NULL,
[title] NVARCHAR(200) NOT NULL,
[url] NVARCHAR(200) NOT NULL,
[completed] BIT NOT NULL
);
Trigger HTTP, ottenere riga per ID dalla stringa di query
L'esempio seguente mostra un'associazione di input di Azure SQL in un file function.json e una funzione script C# che usa l'associazione. La funzione viene attivata da una richiesta HTTP che usa una stringa di query per specificare l'ID. Tale ID viene usato per recuperare un record ToDoItem
con la query specificata.
Nota
Il parametro di stringa di query HTTP fa distinzione tra maiuscole e minuscole.
Ecco i dati di associazione nel file function.json:
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"name": "todoItem",
"type": "sql",
"direction": "in",
"commandText": "select [Id], [order], [title], [url], [completed] from dbo.ToDo where Id = @Id",
"commandType": "Text",
"parameters": "@Id = {Query.id}",
"connectionStringSetting": "SqlConnectionString"
}
Ecco il codice script C#:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System.Collections.Generic;
public static IActionResult Run(HttpRequest req, ILogger log, IEnumerable<ToDoItem> todoItem)
{
return new OkObjectResult(todoItem);
}
Trigger HTTP, eliminazione di righe
L'esempio seguente illustra un'associazione di input SQL di Azure in un file function.json e una funzione script C# che usa l'associazione per eseguire una stored procedure con input dal parametro di query della richiesta HTTP. In questo esempio, la stored procedure elimina un singolo record o tutti i record a seconda del valore del parametro.
La stored procedure dbo.DeleteToDo
deve essere creata nel database SQL.
CREATE PROCEDURE [dbo].[DeleteToDo]
@Id NVARCHAR(100)
AS
DECLARE @UID UNIQUEIDENTIFIER = TRY_CAST(@ID AS UNIQUEIDENTIFIER)
IF @UId IS NOT NULL AND @Id != ''
BEGIN
DELETE FROM dbo.ToDo WHERE Id = @UID
END
ELSE
BEGIN
DELETE FROM dbo.ToDo WHERE @ID = ''
END
SELECT [Id], [order], [title], [url], [completed] FROM dbo.ToDo
GO
Ecco i dati di associazione nel file function.json:
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"name": "todoItems",
"type": "sql",
"direction": "in",
"commandText": "DeleteToDo",
"commandType": "StoredProcedure",
"parameters": "@Id = {Query.id}",
"connectionStringSetting": "SqlConnectionString"
}
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
namespace AzureSQL.ToDo
{
public static class DeleteToDo
{
// delete all items or a specific item from querystring
// returns remaining items
// uses input binding with a stored procedure DeleteToDo to delete items and return remaining items
[FunctionName("DeleteToDo")]
public static IActionResult Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "delete", Route = "DeleteFunction")] HttpRequest req,
ILogger log,
[Sql(commandText: "DeleteToDo", commandType: System.Data.CommandType.StoredProcedure,
parameters: "@Id={Query.id}", connectionStringSetting: "SqlConnectionString")]
IEnumerable<ToDoItem> toDoItems)
{
return new OkObjectResult(toDoItems);
}
}
}
Ecco il codice script C#:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System.Collections.Generic;
public static IActionResult Run(HttpRequest req, ILogger log, IEnumerable<ToDoItem> todoItems)
{
return new OkObjectResult(todoItems);
}
Output SQL di Azure
Altri esempi per l'associazione dell'output Azure SQL sono disponibili nel repository GitHub.
Questa sezione contiene gli esempi seguenti:
Gli esempi fanno riferimento a una classe ToDoItem
e a una tabella di database corrispondente:
namespace AzureSQL.ToDo
{
public class ToDoItem
{
public Guid Id { get; set; }
public int? order { get; set; }
public string title { get; set; }
public string url { get; set; }
public bool? completed { get; set; }
}
}
CREATE TABLE dbo.ToDo (
[Id] UNIQUEIDENTIFIER PRIMARY KEY,
[order] INT NULL,
[title] NVARCHAR(200) NOT NULL,
[url] NVARCHAR(200) NOT NULL,
[completed] BIT NOT NULL
);
Trigger HTTP, scrittura di record in una tabella
L'esempio seguente illustra un'associazione di output SQL in un file function.json e una funzione script C# che aggiunge record a una tabella, usando i dati forniti in una richiesta HTTP POST come corpo JSON.
Di seguito sono riportati i dati di associazione nel file function.json:
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"name": "todoItem",
"type": "sql",
"direction": "out",
"commandText": "dbo.ToDo",
"connectionStringSetting": "SqlConnectionString"
}
Di seguito è riportato il codice di script C# di esempio:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
public static IActionResult Run(HttpRequest req, ILogger log, out ToDoItem todoItem)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string requestBody = new StreamReader(req.Body).ReadToEnd();
todoItem = JsonConvert.DeserializeObject<ToDoItem>(requestBody);
return new OkObjectResult(todoItem);
}
Trigger HTTP, scrittura in due tabelle
L'esempio seguente illustra un'associazione di output SQL in un file function.json e una funzione script C# che aggiunge record a un database in due tabelle diverse (dbo.ToDo
e dbo.RequestLog
), usando i dati forniti in una richiesta HTTP POST come corpo JSON e più associazioni di output.
La seconda tabella, dbo.RequestLog
, corrisponde alla definizione seguente:
CREATE TABLE dbo.RequestLog (
Id int identity(1,1) primary key,
RequestTimeStamp datetime2 not null,
ItemCount int not null
)
Di seguito sono riportati i dati di associazione nel file function.json:
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"name": "todoItem",
"type": "sql",
"direction": "out",
"commandText": "dbo.ToDo",
"connectionStringSetting": "SqlConnectionString"
},
{
"name": "requestLog",
"type": "sql",
"direction": "out",
"commandText": "dbo.RequestLog",
"connectionStringSetting": "SqlConnectionString"
}
Di seguito è riportato il codice di script C# di esempio:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
public static IActionResult Run(HttpRequest req, ILogger log, out ToDoItem todoItem, out RequestLog requestLog)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string requestBody = new StreamReader(req.Body).ReadToEnd();
todoItem = JsonConvert.DeserializeObject<ToDoItem>(requestBody);
requestLog = new RequestLog();
requestLog.RequestTimeStamp = DateTime.Now;
requestLog.ItemCount = 1;
return new OkObjectResult(todoItem);
}
public class RequestLog {
public DateTime RequestTimeStamp { get; set; }
public int ItemCount { get; set; }
}
Output RabbitMQ
L'esempio seguente mostra un'associazione di output di RabbitMQ in un file function.json e una funzione script C# che usa l'associazione. La funzione legge il messaggio da un trigger HTTP e lo restituisce nella coda RabbitMQ.
Ecco i dati di associazione nel file function.json:
{
"bindings": [
{
"type": "httpTrigger",
"direction": "in",
"authLevel": "function",
"name": "input",
"methods": [
"get",
"post"
]
},
{
"type": "rabbitMQ",
"name": "outputMessage",
"queueName": "outputQueue",
"connectionStringSetting": "rabbitMQConnectionAppSetting",
"direction": "out"
}
]
}
Ecco il codice script C#:
using System;
using Microsoft.Extensions.Logging;
public static void Run(string input, out string outputMessage, ILogger log)
{
log.LogInformation(input);
outputMessage = input;
}
Output di SendGrid
L'esempio seguente mostra un'associazione di output di SendGrid in un file function.json e una funzione script C# che usa l'associazione.
Ecco i dati di associazione nel file function.json:
{
"bindings": [
{
"type": "queueTrigger",
"name": "mymsg",
"queueName": "myqueue",
"connection": "AzureWebJobsStorage",
"direction": "in"
},
{
"type": "sendGrid",
"name": "$return",
"direction": "out",
"apiKey": "SendGridAPIKeyAsAppSetting",
"from": "{FromEmail}",
"to": "{ToEmail}"
}
]
}
Ecco il codice script C#:
#r "SendGrid"
using System;
using SendGrid.Helpers.Mail;
using Microsoft.Azure.WebJobs.Host;
public static SendGridMessage Run(Message mymsg, ILogger log)
{
SendGridMessage message = new SendGridMessage()
{
Subject = $"{mymsg.Subject}"
};
message.AddContent("text/plain", $"{mymsg.Content}");
return message;
}
public class Message
{
public string ToEmail { get; set; }
public string FromEmail { get; set; }
public string Subject { get; set; }
public string Content { get; set; }
}
Trigger SignalR
Ecco un esempio di dati di associazione nel file function.json:
{
"type": "signalRTrigger",
"name": "invocation",
"hubName": "SignalRTest",
"category": "messages",
"event": "SendMessage",
"parameterNames": [
"message"
],
"direction": "in"
}
Ed ecco il codice:
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using System;
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
using Microsoft.Extensions.Logging;
public static void Run(InvocationContext invocation, string message, ILogger logger)
{
logger.LogInformation($"Receive {message} from {invocationContext.ConnectionId}.");
}
Input signalR
L'esempio seguente mostra un'associazione di input delle informazioni di connessione a SignalR in un file function.json e una funzione script C# che usa l'associazione per restituire le informazioni di connessione.
Ecco i dati di associazione nel file function.json:
Esempio di function.json:
{
"type": "signalRConnectionInfo",
"name": "connectionInfo",
"hubName": "chat",
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
"direction": "in"
}
Ecco il codice dello script C#:
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
public static SignalRConnectionInfo Run(HttpRequest req, SignalRConnectionInfo connectionInfo)
{
return connectionInfo;
}
È possibile impostare la proprietà userId
dell'associazione sul valore ottenuto da una delle intestazioni con un'espressione di associazione: {headers.x-ms-client-principal-id}
o {headers.x-ms-client-principal-name}
.
Esempio di function.json:
{
"type": "signalRConnectionInfo",
"name": "connectionInfo",
"hubName": "chat",
"userId": "{headers.x-ms-client-principal-id}",
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
"direction": "in"
}
Ecco il codice dello script C#:
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
public static SignalRConnectionInfo Run(HttpRequest req, SignalRConnectionInfo connectionInfo)
{
// connectionInfo contains an access key token with a name identifier
// claim set to the authenticated user
return connectionInfo;
}
Output di SignalR
Ecco i dati di associazione nel file function.json:
Esempio di function.json:
{
"type": "signalR",
"name": "signalRMessages",
"hubName": "<hub_name>",
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
"direction": "out"
}
Ecco il codice dello script C#:
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
public static Task Run(
object message,
IAsyncCollector<SignalRMessage> signalRMessages)
{
return signalRMessages.AddAsync(
new SignalRMessage
{
Target = "newMessage",
Arguments = new [] { message }
});
}
È possibile inviare un messaggio solo alle connessioni autenticate per un utente impostando la proprietà ID utente del messaggio SignalR.
Esempio di function.json:
{
"type": "signalR",
"name": "signalRMessages",
"hubName": "<hub_name>",
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
"direction": "out"
}
Ecco il codice script C#:
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
public static Task Run(
object message,
IAsyncCollector<SignalRMessage> signalRMessages)
{
return signalRMessages.AddAsync(
new SignalRMessage
{
// the message will only be sent to this user ID
UserId = "userId1",
Target = "newMessage",
Arguments = new [] { message }
});
}
È possibile inviare un messaggio solo alle connessioni aggiunte a un gruppo impostando il nome del gruppo nel messaggio SignalR.
Esempio di function.json:
{
"type": "signalR",
"name": "signalRMessages",
"hubName": "<hub_name>",
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
"direction": "out"
}
Ecco il codice dello script C#:
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
public static Task Run(
object message,
IAsyncCollector<SignalRMessage> signalRMessages)
{
return signalRMessages.AddAsync(
new SignalRMessage
{
// the message will be sent to the group with this name
GroupName = "myGroup",
Target = "newMessage",
Arguments = new [] { message }
});
}
Il servizio SignalR consente di aggiungere utenti o connessioni ai gruppi. I messaggi possono quindi essere inviati a un gruppo. È possibile usare l'associazione di output SignalR
per gestire i gruppi.
Nell'esempio seguente viene aggiunto un utente a un gruppo.
Esempio di function.jslon
{
"type": "signalR",
"name": "signalRGroupActions",
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
"hubName": "chat",
"direction": "out"
}
Run.csx
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
public static Task Run(
HttpRequest req,
ClaimsPrincipal claimsPrincipal,
IAsyncCollector<SignalRGroupAction> signalRGroupActions)
{
var userIdClaim = claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier);
return signalRGroupActions.AddAsync(
new SignalRGroupAction
{
UserId = userIdClaim.Value,
GroupName = "myGroup",
Action = GroupAction.Add
});
}
Nell'esempio seguente viene rimosso un utente da un gruppo.
Esempio di function.jslon
{
"type": "signalR",
"name": "signalRGroupActions",
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
"hubName": "chat",
"direction": "out"
}
Run.csx
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
public static Task Run(
HttpRequest req,
ClaimsPrincipal claimsPrincipal,
IAsyncCollector<SignalRGroupAction> signalRGroupActions)
{
var userIdClaim = claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier);
return signalRGroupActions.AddAsync(
new SignalRGroupAction
{
UserId = userIdClaim.Value,
GroupName = "myGroup",
Action = GroupAction.Remove
});
}
Output di Twilio
L'esempio seguente mostra un'associazione di output di Twilio in un file function.json e una funzione script C# che usa l'associazione. La funzione usa un parametro out
per inviare un messaggio di testo.
Ecco i dati di associazione nel file function.json:
Esempio di function.json:
{
"type": "twilioSms",
"name": "message",
"accountSidSetting": "TwilioAccountSid",
"authTokenSetting": "TwilioAuthToken",
"from": "+1425XXXXXXX",
"direction": "out",
"body": "Azure Functions Testing"
}
Ecco il codice script C#:
#r "Newtonsoft.Json"
#r "Twilio"
#r "Microsoft.Azure.WebJobs.Extensions.Twilio"
using System;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Azure.WebJobs.Extensions.Twilio;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;
public static void Run(string myQueueItem, out CreateMessageOptions message, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
// In this example the queue item is a JSON string representing an order that contains the name of a
// customer and a mobile number to send text updates to.
dynamic order = JsonConvert.DeserializeObject(myQueueItem);
string msg = "Hello " + order.name + ", thank you for your order.";
// You must initialize the CreateMessageOptions variable with the "To" phone number.
message = new CreateMessageOptions(new PhoneNumber("+1704XXXXXXX"));
// A dynamic message can be set instead of the body in the output binding. In this example, we use
// the order information to personalize a text message.
message.Body = msg;
}
Non è possibile usare parametri out nel codice asincrono. Ecco un esempio di codice script C# asincrono:
#r "Newtonsoft.Json"
#r "Twilio"
#r "Microsoft.Azure.WebJobs.Extensions.Twilio"
using System;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Azure.WebJobs.Extensions.Twilio;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;
public static async Task Run(string myQueueItem, IAsyncCollector<CreateMessageOptions> message, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
// In this example the queue item is a JSON string representing an order that contains the name of a
// customer and a mobile number to send text updates to.
dynamic order = JsonConvert.DeserializeObject(myQueueItem);
string msg = "Hello " + order.name + ", thank you for your order.";
// You must initialize the CreateMessageOptions variable with the "To" phone number.
CreateMessageOptions smsText = new CreateMessageOptions(new PhoneNumber("+1704XXXXXXX"));
// A dynamic message can be set instead of the body in the output binding. In this example, we use
// the order information to personalize a text message.
smsText.Body = msg;
await message.AddAsync(smsText);
}
Trigger di riscaldamento
L'esempio seguente mostra un trigger di riscaldamento in un file function.json e una funzione script C# eseguita in ogni nuova istanza quando viene aggiunta all'app.
Non supportato per la versione 1.x del runtime di Funzioni.
Ecco il file function.json:
{
"bindings": [
{
"type": "warmupTrigger",
"direction": "in",
"name": "warmupContext"
}
]
}
public static void Run(WarmupContext warmupContext, ILogger log)
{
log.LogInformation("Function App instance is warm.");
}