

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Compilazione di funzioni Lambda con C\$1
<a name="lambda-csharp"></a>

Puoi eseguire l'applicazione.NET in Lambda utilizzando il runtime gestito.NET 8, un runtime personalizzato o un'immagine del contenitore. Dopo aver compilato il codice dell'applicazione, potrai implementarlo su Lambda come file .zip o come immagine di container. Lambda fornisce i runtime seguenti per i linguaggi .NET:


| Name | Identificatore | Sistema operativo | Data di ritiro | Blocco creazione funzioni | Blocco aggiornamento funzioni | 
| --- | --- | --- | --- | --- | --- | 
|  .NET 10  |  `dotnet10`  |  Amazon Linux 2023  |   14 novembre 2028   |   14 dicembre 2028   |   15 gennaio 2029   | 
|  .NET 9 (solo contenitore)  |  `dotnet9`  |  Amazon Linux 2023  |   10 novembre 2026   |   Non programmato   |   Non programmato   | 
|  .NET 8  |  `dotnet8`  |  Amazon Linux 2023  |   10 novembre 2026   |   10 dicembre 2026   |   11 gennaio 2027   | 

## Configurazione dell'ambiente di sviluppo .NET
<a name="csharp-dev-env"></a>

Per sviluppare e creare le funzioni Lambda, puoi utilizzare uno qualsiasi degli ambienti di sviluppo integrati.NET comunemente disponibili (IDEs), inclusi Microsoft Visual Studio, Visual Studio Code e JetBrains Rider. Per semplificare l'esperienza di sviluppo, AWS fornisce un set di modelli di progetto.NET e l'interfaccia a riga di `Amazon.Lambda.Tools` comando (CLI).

Emetti i seguenti comandi .NET della CLI per installare questi modelli di progetto e strumenti da riga di comando.

### Installazione dei modelli di progetto .NET
<a name="csharp-dev-env-templates"></a>

Per installare i modelli di progetto, esegui il comando riportato:

```
dotnet new install Amazon.Lambda.Templates
```

### Installazione e aggiornamento degli strumenti della CLI
<a name="csharp-dev-env-cli-tools"></a>

Esegui i comandi riportati qui di seguito per installare, aggiornare e disinstallare la CLI di `Amazon.Lambda.Tools`.

Per installare gli strumenti a riga di comando:

```
dotnet tool install -g Amazon.Lambda.Tools
```

Per aggiornare gli strumenti a riga di comando:

```
dotnet tool update -g Amazon.Lambda.Tools
```

Per disinstallare gli strumenti a riga di comando:

```
dotnet tool uninstall -g Amazon.Lambda.Tools
```

# Definire l'handler della funzione Lambda in C\$1
<a name="csharp-handler"></a>

Il *gestore* di funzioni Lambda è il metodo nel codice della funzione che elabora gli eventi. Quando viene richiamata la funzione, Lambda esegue il metodo del gestore. La funzione viene eseguita fino a quando il gestore non restituisce una risposta, termina o scade.

Questa pagina descrive come lavorare con i gestori di funzioni Lambda in C\$1 per operare con il runtime gestito da .NET, incluse le opzioni per la configurazione del progetto, le convenzioni di denominazione e le best practice. Questa pagina include anche un esempio di funzione Lambda C\$1 che raccoglie informazioni su un ordine, produce una ricevuta in un file di testo e inserisce questo file in un bucket Amazon Simple Storage Service (S3). Per informazioni su come distribuire una funzione dopo averla scritta, consulta o. [Crea e implementa le funzioni Lambda C\$1 con gli archivi di file .zip](csharp-package.md) [Distribuzione delle funzioni .NET Lambda con immagini di container](csharp-image.md)

**Topics**
+ [

## Configurazione del progetto del gestore C\$1
](#csharp-handler-setup)
+ [

## Esempio di codice della funzione Lambda C\$1
](#csharp-example-code)
+ [

## Gestori di librerie di classi
](#csharp-class-library-handlers)
+ [

## Gestori di assembly eseguibili
](#csharp-executable-assembly-handlers)
+ [

## Firme del gestore valide per le funzioni C\$1
](#csharp-handler-signatures)
+ [

## Convenzioni di denominazione dei gestori
](#csharp-handler-naming)
+ [

## Serializzazione nelle funzioni Lambda C\$1
](#csharp-handler-serializer)
+ [

## Funzioni basate su file
](#csharp-file-based-functions)
+ [

## Accesso e utilizzo dell'oggetto contestuale Lambda
](#csharp-example-context)
+ [

## Usando la SDK per .NET v3 nel tuo gestore
](#csharp-example-sdk-usage)
+ [

## Accesso alle variabili d'ambiente
](#csharp-example-envvars)
+ [

## Utilizzo dello stato globale
](#csharp-handler-state)
+ [

## Semplificazione del codice delle funzioni con il framework Lambda Annotations
](#csharp-handler-annotations)
+ [

## Best practice di codice per le funzioni Lambda con C\$1
](#csharp-best-practices)

## Configurazione del progetto del gestore C\$1
<a name="csharp-handler-setup"></a>

Quando lavori con le funzioni Lambda in C\$1, il processo prevede la scrittura del codice, quindi l’implementazione del codice in Lambda. Esistono due diversi modelli di esecuzione per l’implementazione delle funzioni Lambda in .NET: l'approccio della libreria di classi e l'approccio dell'assembly eseguibile.

Quando segui l'approccio della libreria di classi, impacchetti il codice della funzione come assembly .NET (`.dll`) e lo implementi in Lambda con il runtime gestito da .NET (`dotnet8`). Per il nome del gestore, Lambda si aspetta una stringa nel formato `AssemblyName::Namespace.Classname::Methodname`. Durante la fase di inizializzazione della funzione, la classe della funzione viene inizializzata e viene eseguito qualsiasi codice nel costruttore.

Quando segui l'approccio dell'assembly eseguibile, utilizzi la [funzionalità delle istruzioni di primo livello](https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/top-level-statements) introdotta per la prima volta in C\$1 9. Questo approccio genera un assembly eseguibile che Lambda esegue ogni volta che riceve un comando invoke per la tua funzione. Con questo approccio, utilizzi anche il runtime gestito da .NET (`dotnet8`). Per il nome del gestore, fornisci a Lambda il nome dell'assembly eseguibile da eseguire.

L'esempio principale in questa pagina illustra l'approccio delle librerie di classi. Puoi inizializzare il progetto C\$1 Lambda in vari modi, ma il modo più semplice è utilizzare l'interfaccia CLI .NET con la CLI `Amazon.Lambda.Tools`. Configura la CLI `Amazon.Lambda.Tools` seguendo i passaggi indicati in [Configurazione dell'ambiente di sviluppo .NET](lambda-csharp.md#csharp-dev-env). Quindi, inizializza il progetto con il seguente comando.

```
dotnet new lambda.EmptyFunction --name ExampleCS
```

Questo comando genera la seguente struttura di file:

```
/project-root 
    └ src
        └ ExampleCS
            └ Function.cs (contains main handler)
            └ Readme.md
            └ aws-lambda-tools-defaults.json
            └ ExampleCS.csproj          
    └ test
         └ ExampleCS.Tests
            └ FunctionTest.cs (contains main handler)
            └ ExampleCS.Tests.csproj
```

In questa struttura di file, la logica del gestore principale per la funzione risiede nel file `Function.cs`.

## Esempio di codice della funzione Lambda C\$1
<a name="csharp-example-code"></a>

Il seguente esempio di codice della funzione Lambda C\$1 raccoglie le informazioni su un ordine, produce una ricevuta in un file di testo e inserisce questo file in un bucket Amazon S3.

**Example Funzione Lambda `Function.cs`**  

```
using System;
using System.Text;
using System.Threading.Tasks;
using Amazon.Lambda.Core;
using Amazon.S3;
using Amazon.S3.Model;

// Assembly attribute to enable Lambda function logging
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace ExampleLambda;

public class Order
{
    public string OrderId { get; set; } = string.Empty;
    public double Amount { get; set; }
    public string Item { get; set; } = string.Empty;
}

public class OrderHandler
{
    private static readonly AmazonS3Client s3Client = new();

    public async Task<string> HandleRequest(Order order, ILambdaContext context)
    {
        try
        {
            string? bucketName = Environment.GetEnvironmentVariable("RECEIPT_BUCKET");
            if (string.IsNullOrWhiteSpace(bucketName))
            {
                throw new ArgumentException("RECEIPT_BUCKET environment variable is not set");
            }

            string receiptContent = $"OrderID: {order.OrderId}\nAmount: ${order.Amount:F2}\nItem: {order.Item}";
            string key = $"receipts/{order.OrderId}.txt";

            await UploadReceiptToS3(bucketName, key, receiptContent);

            context.Logger.LogInformation($"Successfully processed order {order.OrderId} and stored receipt in S3 bucket {bucketName}");
            return "Success";
        }
        catch (Exception ex)
        {
            context.Logger.LogError($"Failed to process order: {ex.Message}");
            throw;
        }
    }

    private async Task UploadReceiptToS3(string bucketName, string key, string receiptContent)
    {
        try
        {
            var putRequest = new PutObjectRequest
            {
                BucketName = bucketName,
                Key = key,
                ContentBody = receiptContent,
                ContentType = "text/plain"
            };

            await s3Client.PutObjectAsync(putRequest);
        }
        catch (AmazonS3Exception ex)
        {
            throw new Exception($"Failed to upload receipt to S3: {ex.Message}", ex);
        }
    }
}
```

Questo file `Function.cs` contiene le sezioni seguenti:
+ Istruzioni `using`: usale per importare le classi C\$1 richieste dalla funzione Lambda.
+ `[assembly: LambdaSerializer(...)]`: `LambdaSerializer` è un attributo assembly che indica a Lambda di convertire automaticamente i payload di eventi JSON in oggetti C\$1 prima di passarli alla funzione.
+ `namespace ExampleLambda`: definisce il namespace. In C\$1, il nome del namespace non deve corrispondere al nome del file.
+ `public class Order {...}`: definisce la forma dell'evento di input previsto.
+ `public class OrderHandler {...}`: definisce la tua classe C\$1. Al suo interno, definirai il metodo del gestore principale e qualsiasi altro metodo di supporto.
+ `private static readonly AmazonS3Client s3Client = new();`: inizializza un client Amazon S3 con la catena di provider delle credenziali predefinita, al di fuori del metodo del gestore principale. Ciò fa sì che Lambda esegua questo codice durante la [fase di inizializzazione](lambda-runtime-environment.md#runtimes-lifecycle-ib).
+ `public async ... HandleRequest (Order order, ILambdaContext context)`: questo è il **metodo dell'handler principale**, che contiene la logica principale dell'applicazione.
+ `private async Task UploadReceiptToS3(...) {}`: questo è un metodo helper a cui fa riferimento il metodo dell'handler principale `handleRequest`.

Poiché questa funzione richiede un client SDK Amazon S3, devi aggiungerlo alle dipendenze del progetto. Puoi farlo andando in `src/ExampleCS` e impartendo il comando seguente:

```
dotnet add package AWSSDK.S3
```

### Aggiungi informazioni sui metadati a.json aws-lambda-tools-defaults
<a name="csharp-metadata-example"></a>

Per impostazione predefinita, il file `aws-lambda-tools-defaults.json` generato non contiene informazioni `profile` o `region` sulla tua funzione. Inoltre, aggiorna la stringa `function-handler` al valore corretto (`ExampleCS::ExampleLambda.OrderHandler::HandleRequest`). Puoi effettuare questo aggiornamento manualmente e aggiungere i metadati necessari per utilizzare un profilo di credenziali e una regione specifici per la tua funzione. Ad esempio, il file `aws-lambda-tools-defaults.json` dovrebbe essere simile all'esempio seguente:

```
{
  "Information": [
    "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.",
    "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.",
    "dotnet lambda help",
    "All the command line options for the Lambda command can be specified in this file."
  ],
  "profile": "default",
  "region": "us-east-1",
  "configuration": "Release",
  "function-architecture": "x86_64",
  "function-runtime": "dotnet8",
  "function-memory-size": 512,
  "function-timeout": 30,
  "function-handler": "ExampleCS::ExampleLambda.OrderHandler::HandleRequest"
}
```

Affinché questa funzione funzioni correttamente, il suo [ruolo di esecuzione](lambda-intro-execution-role.md) deve consentire l'`s3:PutObject`azione. Inoltre, assicuratevi di definire la variabile di `RECEIPT_BUCKET` ambiente. Dopo una chiamata riuscita, il bucket Amazon S3 dovrebbe contenere un file di ricevuta.

## Gestori di librerie di classi
<a name="csharp-class-library-handlers"></a>

Il [codice di esempio](#csharp-example-code) principale in questa pagina illustra un gestore di librerie di classi. I gestori di librerie di classi hanno la seguente struttura:

```
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace NAMESPACE;

...

public class CLASSNAME {
    public async Task<string> METHODNAME (...) {
    ...
    }
}
```

Quando crei una funzione Lambda, devi fornire a Lambda informazioni sul gestore della funzione sotto forma di stringa nel [campo Gestore](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-Handler). Questo indica a Lambda quale metodo del codice eseguire quando la funzione viene richiamata. In C\$1, per i gestori di librerie di classi, il formato della stringa del gestore è `ASSEMBLY::TYPE::METHOD`, dove:
+ `ASSEMBLY` è il nome del file di assembly .NET per l'applicazione. Se stai usando `Amazon.Lambda.Tools` CLI per creare l’applicazione e non specifichi il nome dell'assembly con la proprietà `AssemblyName` nel file `.csproj`, allora `ASSEMBLY` è semplicemente il nome del file `.csproj`.
+ `TYPE` è il nome completo del tipo di gestore, cioè `NAMESPACE.CLASSNAME`.
+ `METHOD` è il nome del metodo del gestore principale nel codice, cioè `METHODNAME`.

Per il codice di esempio principale, se l'assembly è denominato `ExampleCS`, la stringa completa del gestore è `ExampleCS::ExampleLambda.OrderHandler::HandleRequest`.

## Gestori di assembly eseguibili
<a name="csharp-executable-assembly-handlers"></a>

È inoltre possibile definire le funzioni Lambda in C\$1 come assembly eseguibile. I gestori di assembly eseguibili utilizzano la funzionalità delle istruzioni di primo livello di C\$1, in cui il compilatore genera il metodo `Main()` e inserisce il codice della funzione al suo interno. Quando si utilizzano assembly eseguibili, è necessario avviare il runtime Lambda. Per far ciò, utilizza il metodo `LambdaBootstrapBuilder.Create` nel codice. Gli input per questo metodo sono la funzione del gestore principale e il serializzatore Lambda da utilizzare. Di seguito viene illustrato un esempio di gestore di assembly eseguibile in C\$1:

```
namespace GetProductHandler;

IDatabaseRepository repo = new DatabaseRepository();

await LambdaBootstrapBuilder.Create<APIGatewayProxyRequest>(Handler, new DefaultLambdaJsonSerializer())
    .Build()
    .RunAsync();

async Task<APIGatewayProxyResponse> Handler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context)
{
    var id = apigProxyEvent.PathParameters["id"];
    var databaseRecord = await this.repo.GetById(id);
    
    return new APIGatewayProxyResponse 
    {
        StatusCode = (int)HttpStatusCode.OK,
        Body = JsonSerializer.Serialize(databaseRecord)
    };
};
```

Nel [campo Gestore](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-Handler) per i gestori di assembly eseguibili, la stringa del gestore che indica a Lambda come eseguire il codice è il nome dell'assembly. In questo esempio è `GetProductHandler`.

## Firme del gestore valide per le funzioni C\$1
<a name="csharp-handler-signatures"></a>

In C\$1, le firme del gestore Lambda valide richiedono da 0 a 2 argomenti. In genere, la firma del gestore ha due argomenti, come mostrato nell'esempio principale:

```
public async Task<string> HandleRequest(Order order, ILambdaContext context)
```

Quando si forniscono due argomenti, il primo argomento deve essere l'input dell'evento e il secondo argomento deve essere l'oggetto del contesto Lambda. Entrambi gli argomenti sono facoltativi. Ad esempio, le seguenti sono anche firme valide di gestori Lambda in C\$1:
+ `public async Task<string> HandleRequest()`
+ `public async Task<string> HandleRequest(Order order)`
+ `public async Task<string> HandleRequest(ILambdaContext context)`

Oltre alla sintassi di base della firma del gestore, esistono alcune restrizioni aggiuntive:
+ Non è possibile utilizzare la parola chiave `unsafe` nella firma del gestore. Tuttavia, puoi utilizzare il contesto `unsafe` all'interno del metodo del gestore e delle sue dipendenze. Per ulteriori informazioni, consulta [unsafe (Riferimenti per C\$1)](https://msdn.microsoft.com/en-us/library/chfa2zb8.aspx) sul sito Web di Microsoft.
+ Il gestore potrebbe non utilizzare la parola chiave `params`, o usare `ArgIterator` come parametro di input o di ritorno. Queste parole chiave supportano un numero variabile di parametri. Il gestore può accettare al massimo due argomenti.
+ Il gestore potrebbe non essere un metodo generico. In altre parole, non può utilizzare parametri di tipo generico come `<T>`.
+ Lambda non supporta gestori asincroni con `async void` nella firma.

## Convenzioni di denominazione dei gestori
<a name="csharp-handler-naming"></a>

I gestori Lambda in C\$1 non hanno restrizioni di denominazione rigide. Tuttavia, devi assicurarti di fornire la stringa del gestore corretta a Lambda quando implementi la funzione. La stringa del gestore corretta dipende da se stai implementando un [gestore di libreria di classi](#csharp-class-library-handlers) o un [gestore di assembly eseguibile](#csharp-executable-assembly-handlers).

Sebbene sia possibile utilizzare qualsiasi nome per il gestore, i nomi delle funzioni in C\$1 sono generalmente in. PascalCase Inoltre, sebbene non sia necessario che il nome del file corrisponda al nome della classe o del gestore, in genere è consigliabile utilizzare un nome di file come `OrderHandler.cs` se il nome della classe è `OrderHandler`. Ad esempio, è possibile modificare il nome del file in questo esempio da `Function.cs` a `OrderHandler.cs`.

## Serializzazione nelle funzioni Lambda C\$1
<a name="csharp-handler-serializer"></a>

JSON è il formato di input più comune e standard per le funzioni Lambda. In questo esempio, la funzione prevede un input simile a quanto segue:

```
{
    "orderId": "12345",
    "amount": 199.99,
    "item": "Wireless Headphones"
}
```

In C\$1, puoi definire la forma dell'evento di input previsto in una classe. In questo esempio, definiamo la classe `Order` per modellare questo input:

```
public class Order
{
    public string OrderId { get; set; } = string.Empty;
    public double Amount { get; set; }
    public string Item { get; set; } = string.Empty;
}
```

Se la funzione Lambda utilizza i tipi di input/output diversi da un oggetto `Stream`, è necessario aggiungere una libreria di serializzazione all'applicazione. Ciò ti consente di convertire l'input JSON in un'istanza della classe definita. Esistono due metodi di serializzazione per le funzioni C\$1 in Lambda: serializzazione basata sulla riflessione e serializzazione generata dal codice sorgente.

### Serializzazione basata sulla riflessione
<a name="csharp-reflection-based-serialization"></a>

AWS fornisce librerie predefinite che è possibile aggiungere rapidamente all'applicazione. Queste librerie implementano la serializzazione utilizzando la [riflessione](https://learn.microsoft.com/en-us/dotnet/csharp/advanced-topics/reflection-and-attributes/). Utilizza uno dei seguenti pacchetti per implementare la serializzazione basata sulla riflessione:
+ `Amazon.Lambda.Serialization.SystemTextJson`: nel backend, questo pacchetto utilizza `System.Text.Json` per eseguire attività di serializzazione.
+ `Amazon.Lambda.Serialization.Json`: nel backend, questo pacchetto utilizza `Newtonsoft.Json` per eseguire attività di serializzazione.

È possibile inoltre creare una libreria di serializzazione personalizzata implementando l'interfaccia `ILambdaSerializer`, disponibile come parte della libreria `Amazon.Lambda.Core`. L'interfaccia definisce due metodi:
+ `T Deserialize<T>(Stream requestStream);`

  Questo metodo viene implementato per deserializzare il payload della richiesta dall'API `Invoke` nell'oggetto passato al gestore della funzione Lambda.
+ `T Serialize<T>(T response, Stream responseStream);`

  Questo metodo viene implementato per serializzare il risultato restituito dal gestore della funzione Lambda nel payload della risposta restituito dall'operazione dell'API `Invoke`.

L'esempio principale in questa pagina utilizza la serializzazione basata sulla riflessione. La serializzazione basata su Reflection funziona immediatamente AWS Lambda e non richiede alcuna configurazione aggiuntiva, il che la rende un'ottima scelta in termini di semplicità. Tuttavia, richiede un maggiore utilizzo della memoria funzionale. È inoltre possibile che si verifichino latenze di funzioni più elevate a causa della riflessione del runtime.

### Serializzazione generata dal codice sorgente
<a name="csharp-source-generated-serialization"></a>

Con la serializzazione generata dal codice sorgente, il codice di serializzazione viene generato in fase di compilazione. Ciò elimina la necessità di riflessione e può migliorare le prestazioni della tua funzione. Per utilizzare la serializzazione generata dal codice sorgente nella tua funzione, devi procedere come indicato di seguito:
+ Crea una nuova classe parziale che eredita da `JsonSerializerContext`, aggiungendo attributi `JsonSerializable` per tutti i tipi che richiedono la serializzazione o la deserializzazione.
+ Configura il `LambdaSerializer` per utilizzare un `SourceGeneratorLambdaJsonSerializer<T>`.
+ Aggiorna qualsiasi serializzazione e deserializzazione manuale nel codice dell'applicazione per utilizzare la classe appena creata.

L'esempio seguente mostra come puoi modificare l'esempio principale di questa pagina, che utilizza la serializzazione basata sulla riflessione, in modo da utilizzare invece la serializzazione generata dal codice sorgente.

```
using System.Text.Json;
using System.Text.Json.Serialization;

...

public class Order
{
    public string OrderId { get; set; } = string.Empty;
    public double Amount { get; set; }
    public string Item { get; set; } = string.Empty;
}

[JsonSerializable(typeof(Order))]
public partial class OrderJsonContext : JsonSerializerContext {}

public class OrderHandler
{

    ...

    public async Task<string> HandleRequest(string input, ILambdaContext context)
    {
    
    var order = JsonSerializer.Deserialize(input, OrderJsonContext.Default.Order);
    
    ...
    
    }

}
```

La serializzazione generata dal codice sorgente richiede più impostazioni rispetto alla serializzazione basata sulla riflessione. Tuttavia, le funzioni che utilizzano la generazione da codice sorgente tendono a utilizzare meno memoria e offrono prestazioni migliori grazie alla generazione di codice in fase di compilazione. Per contribuire a eliminare gli [avvii a freddo](lambda-runtime-environment.md#cold-start-latency) delle funzioni, prendi in considerazione la possibilità di passare alla serializzazione generata dal codice sorgente.

**Nota**  
Se desideri utilizzare la [ahead-of-time compilazione nativa (AOT)](dotnet-native-aot.md) con Lambda, devi utilizzare la serializzazione generata dal codice sorgente.

## Funzioni basate su file
<a name="csharp-file-based-functions"></a>

Introdotte in .NET 10, le app basate su file consentono di creare applicazioni.NET da un singolo `.cs` file, senza una `.csproj` struttura di file o directory. Lambda supporta funzioni basate su file, a partire da.NET 10. Offrono un modo semplice e leggero per creare funzioni Lambda in C\$1.

Il modo più veloce per iniziare a creare una funzione Lambda basata su file C\$1 consiste nell'utilizzare il pacchetto. `Amazon.Lambda.Templates` Per installare il pacchetto, esegui il comando seguente:

```
dotnet new install Amazon.Lambda.Templates
```

Quindi, crea una funzione Lambda di esempio basata su file C\$1:

```
dotnet new lambda.FileBased -n MyLambdaFunction
```

[Le funzioni basate su file utilizzano gestori di assembly eseguibili.](#csharp-executable-assembly-handlers) È quindi necessario includere il `Amazon.Lambda.RuntimeSupport` NuGet pacchetto e utilizzare il `LambdaBootstrapBuilder.Create` metodo per registrare la funzione di gestore.NET per il tipo di evento e avviare il runtime client .NET Lambda.

Le funzioni basate su file utilizzano.NET Native AOT per impostazione predefinita, che richiede la serializzazione generata dal codice sorgente. È possibile disabilitare Native AOT specificandolo nel file sorgente. `#:property PublishAot=false` Per ulteriori informazioni sull'utilizzo di Native AOT in Lambda, consulta. [Compilare il codice della funzione Lambda .NET in un formato di runtime nativo](dotnet-native-aot.md)

## Accesso e utilizzo dell'oggetto contestuale Lambda
<a name="csharp-example-context"></a>

L'[oggetto contesto](csharp-context.md): contiene informazioni sulla chiamata, sulla funzione e sull'ambiente di esecuzione. In questo esempio, l'oggetto contesto è di tipo `Amazon.Lambda.Core.ILambdaContext` ed è il secondo argomento della funzione del gestore principale.

```
public async Task<string> HandleRequest(Order order, ILambdaContext context) {
    ...
}
```

L'oggetto contesto è un input opzionale. Per ulteriori informazioni sulle firme valide accettate del gestore, consulta [Firme del gestore valide per le funzioni C\$1](#csharp-handler-signatures).

L'oggetto context è utile per produrre log di funzioni su Amazon CloudWatch. Puoi usare il metodo `context.getLogger()` per ottenere un oggetto `LambdaLogger` per la registrazione. In questo esempio, possiamo usare il logger per registrare il log di un messaggio di errore se l'elaborazione fallisce per qualche motivo:

```
context.Logger.LogError($"Failed to process order: {ex.Message}");
```

Oltre alla registrazione di log, puoi anche utilizzare l'oggetto contesto per il monitoraggio delle funzioni. Per ulteriori informazioni sulla copia di oggetti, consulta la sezione [Utilizzo dell'oggetto del contesto Lambda per recuperare le informazioni sulla funzione C\$1](csharp-context.md).

## Usando la SDK per .NET v3 nel tuo gestore
<a name="csharp-example-sdk-usage"></a>

Spesso, utilizzerai le funzioni Lambda per interagire o aggiornare altre AWS risorse. Il modo più semplice per interfacciarsi con queste risorse è usare la SDK per .NET v3.

**Nota**  
La SDK per .NET (v2) è obsoleta. Ti consigliamo di utilizzare solo la versione v3. SDK per .NET 

Puoi aggiungere dipendenze SDK al tuo progetto usando il comando `Amazon.Lambda.Tools` seguente:

```
dotnet add package <package_name>
```

Ad esempio, nell'esempio principale di questa pagina, è necessario utilizzare l'API Amazon S3 per caricare una ricevuta su S3. Possiamo importare il client SDK Amazon S3 con il seguente comando:

```
dotnet add package AWSSDK.S3
```

Questo comando aggiunge la dipendenza al tuo progetto. Dovresti anche vedere una riga simile alla seguente nel file `.csproj` del tuo progetto:

```
<PackageReference Include="AWSSDK.S3" Version="3.7.2.18" />
```

Quindi, importa le dipendenze direttamente nel tuo codice C\$1:

```
using Amazon.S3;
using Amazon.S3.Model;
```

Il codice di esempio inizializza quindi un client Amazon S3 (utilizzando la [catena di provider delle credenziali predefinita](https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html)) come indicato di seguito:

```
private static readonly AmazonS3Client s3Client = new();
```

In questo esempio, abbiamo inizializzato il nostro client Amazon S3 all’esterno della funzione del gestore principale per evitare di doverlo inizializzare ogni volta che invochiamo la nostra funzione. Dopo aver inizializzato il client SDK, puoi utilizzarlo per interagire con altri servizi. AWS Il codice di esempio richiama l'API `PutObject` Amazon S3 nel modo seguente:

```
var putRequest = new PutObjectRequest
{
    BucketName = bucketName,
    Key = key,
    ContentBody = receiptContent,
    ContentType = "text/plain"
};

await s3Client.PutObjectAsync(putRequest);
```

## Accesso alle variabili d'ambiente
<a name="csharp-example-envvars"></a>

Nel codice dell'handler, puoi fare riferimento a qualsiasi [variabile di ambiente](configuration-envvars.md) utilizzando il metodo `System.Environment.GetEnvironmentVariable`. In questo esempio, facciamo riferimento alla variabile di ambiente `RECEIPT_BUCKET` definita utilizzando le seguenti righe di codice:

```
string? bucketName = Environment.GetEnvironmentVariable("RECEIPT_BUCKET");
if (string.IsNullOrWhiteSpace(bucketName))
{
    throw new ArgumentException("RECEIPT_BUCKET environment variable is not set");
}
```

## Utilizzo dello stato globale
<a name="csharp-handler-state"></a>

Lambda esegue il codice statico e il costruttore della classe durante la [fase di inizializzazione](lambda-runtime-environment.md#runtimes-lifecycle-ib) prima di richiamare la funzione per la prima volta. Le risorse create durante l'inizializzazione restano in memoria tra le invocazioni, in modo da evitare di doverle creare ogni volta che si invoca la funzione.

Nel codice di esempio, il codice di inizializzazione del client S3 non rientra nel metodo del gestore principale. Il runtime inizializza il client prima che la funzione gestisca il suo primo evento, il che può portare a tempi di elaborazione più lunghi. Gli eventi successivi sono molto più veloci perché Lambda non ha bisogno di inizializzare nuovamente il client.

## Semplificazione del codice delle funzioni con il framework Lambda Annotations
<a name="csharp-handler-annotations"></a>

[Lambda Annotations](https://www.nuget.org/packages/Amazon.Lambda.Annotations) è un framework per .NET 8 che semplifica la scrittura di funzioni Lambda utilizzando C\$1. Il framework Annotations utilizza [generatori di codice sorgente](https://learn.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/source-generators-overview) per generare codice che si traduce dal modello di programmazione Lambda al codice semplificato. Con il framework Annotations, è possibile sostituire gran parte del codice in una funzione Lambda scritta utilizzando il normale modello di programmazione. Il codice scritto utilizzando il framework utilizza espressioni più semplici che consentono di concentrarsi sulla logica aziendale. Per alcuni esempi, consulta [Amazon.Lambda.Annotations](https://www.nuget.org/packages/Amazon.Lambda.Annotations) nella documentazione NuGet.

Per un esempio di applicazione completa che utilizza le annotazioni Lambda, consulta [ PhotoAssetManager](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3/cross-service/PhotoAssetManager)l'esempio nel repository. `awsdocs/aws-doc-sdk-examples` GitHub Il file `Function.cs` principale nella directory `PamApiAnnotations` usa Lambda Annotations. Per fare un confronto, la directory `PamApi` contiene file equivalenti scritti utilizzando il normale modello di programmazione Lambda.

### Iniezione delle dipendenze con il framework Lambda Annotations
<a name="csharp-handler-annotations-injection"></a>

Puoi utilizzare il framework Lambda Annotations anche per aggiungere l'iniezione di dipendenze alle tue funzioni Lambda utilizzando una sintassi che conosci. Quando aggiungi un attributo `[LambdaStartup]` a un file `Startup.cs`, il framework Lambda Annotations genererà il codice richiesto in fase di compilazione.

```
[LambdaStartup]
public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSingleton<IDatabaseRepository, DatabaseRepository>();
    }
}
```

La tua funzione Lambda può iniettare servizi utilizzando l'iniezione del costruttore o iniettandoli in metodi individuali utilizzando l'attributo `[FromServices]`.

```
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace GetProductHandler;

public class Function
{
    private readonly IDatabaseRepository _repo;
    
    public Function(IDatabaseRepository repo)
    {
        this._repo = repo;
    }
    
    [LambdaFunction]
    [HttpApi(LambdaHttpMethod.Get, "/product/{id}")]
    public async Task<Product> FunctionHandler([FromServices] IDatabaseRepository repository, string id)
    {
        return await this._repo.GetById(id);
    }
}
```

## Best practice di codice per le funzioni Lambda con C\$1
<a name="csharp-best-practices"></a>

Segui le linee guida riportate nell'elenco seguente per utilizzare le best practice di codifica durante la creazione delle funzioni Lambda:
+ **Separare il gestore Lambda dalla logica principale.** In questo modo è possibile creare una funzione di cui è più semplice eseguire l'unit test.
+ **Controllare le dipendenze nel pacchetto di distribuzione della funzione. ** L'ambiente di esecuzione AWS Lambda contiene diverse librerie. Per abilitare il set di caratteristiche e aggiornamenti della sicurezza più recenti, Lambda aggiorna periodicamente tali librerie. Tali aggiornamenti possono introdurre lievi modifiche al comportamento della funzione Lambda. Per mantenere il controllo completo delle dipendenze utilizzate dalla funzione, inserire tutte le dipendenze nel pacchetto di implementazione. 
+ **Ridurre la complessità delle dipendenze.** Preferire framework più semplici che si caricano velocemente all'avvio del [contesto di esecuzione](lambda-runtime-environment.md).
+ **Ridurre al minimo le dimensioni del pacchetto di implementazione al fine di soddisfare le esigenze di runtime. ** In questo modo viene ridotta la quantità di tempo necessaria per il download del pacchetto e per la relativa decompressione prima dell'invocazione. Per le funzioni create in .NET, evitate di caricare l'intera libreria AWS SDK come parte del pacchetto di distribuzione. Utilizzare invece in modo selettivo i moduli che prelevano i componenti dell'SDK necessari (ad esempio i moduli SDK Dynamo DB e Amazon S3 e le librerie di base Lambda). 

**Sfruttare il riutilizzo del contesto di esecuzione per migliorare le prestazioni della funzione.** Inizializzare i client SDK e le connessioni al database all'esterno del gestore di funzioni e memorizzare localmente nella cache gli asset statici nella directory `/tmp`. Le chiamate successive elaborate dalla stessa istanza della funzione possono riutilizzare queste risorse. Ciò consente di risparmiare sui costi riducendo i tempi di esecuzione delle funzioni.

Per evitare potenziali perdite di dati tra le chiamate, non utilizzare il contesto di esecuzione per archiviare dati utente, eventi o altre informazioni con implicazioni di sicurezza. Se la funzione si basa su uno stato mutabile che non può essere archiviato in memoria all'interno del gestore, considerare la possibilità di creare una funzione separata o versioni separate di una funzione per ogni utente.

**Utilizzare una direttiva keep-alive per mantenere le connessioni persistenti.** Lambda elimina le connessioni inattive nel tempo. Se si tenta di riutilizzare una connessione inattiva quando si richiama una funzione, si verificherà un errore di connessione. Per mantenere la connessione persistente, utilizzare la direttiva keep-alive associata al runtime. Per un esempio, vedere [Riutilizzo delle connessioni con Keep-Alive in Node.js](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html).

**Utilizzare [le variabili di ambiente](configuration-envvars.md) per passare i parametri operativi alla funzione.** Se ad esempio si scrive in un bucket Amazon S3 anziché impostare come hard-coded il nome del bucket in cui si esegue la scrittura, configurare tale nome come una variabile di ambiente.

**Evita di usare invocazioni ricorsive** nella tua funzione Lambda, in cui la funzione si richiama da sola o avvia un processo che potrebbe richiamare nuovamente la funzione. Ciò potrebbe provocare un volume non desiderato di invocazioni della funzione e un aumento dei costi. Se noti un volume indesiderato di invocazioni, imposta immediatamente la simultaneità riservata della funzione su `0` per interrompere tutte le invocazioni della funzione mentre si aggiorna il codice.

**Non utilizzare documenti non documentati e non pubblici APIs** nel codice della funzione Lambda. Per i runtime AWS Lambda gestiti, Lambda applica periodicamente aggiornamenti di sicurezza e funzionalità all'interno di Lambda. APIs Questi aggiornamenti delle API interne possono essere incompatibili con le versioni precedenti e portare a conseguenze indesiderate, come errori di chiamata se la funzione dipende da questi elementi non pubblici. APIs [Consulta il riferimento alle API per un elenco di quelle disponibili al pubblico.](https://docs.aws.amazon.com/lambda/latest/api/welcome.html) APIs

**Scrivi un codice idempotente.** La scrittura di un codice idempotente per le tue funzioni garantisce che gli eventi duplicati vengano gestiti allo stesso modo. Il tuo codice dovrebbe convalidare correttamente gli eventi e gestire con garbo gli eventi duplicati. Per ulteriori informazioni, consulta [Come posso rendere idempotente la mia funzione Lambda?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/).

# Crea e implementa le funzioni Lambda C\$1 con gli archivi di file .zip
<a name="csharp-package"></a>

Un pacchetto di implementazione .NET (archivio di file .zip) contiene l'assembly compilato della funzione insieme a tutte le dipendenze dell'assembly stesso. Il pacchetto contiene inoltre un file `proj.deps.json`, Ciò indica al runtime di .NET tutte le dipendenze della funzione e un file `proj.runtimeconfig.json` utilizzato per configurare il runtime.

Per implementare singole funzioni Lambda, puoi utilizzare l'interfaccia a riga di comando globale Lambda .NET `Amazon.Lambda.Tools`. L'utilizzo del comando `dotnet lambda deploy-function` crea automaticamente un pacchetto di implementazione .zip e lo distribuisce su Lambda. Tuttavia, ti consigliamo di utilizzare framework come AWS Serverless Application Model (AWS SAM) o AWS Cloud Development Kit (AWS CDK) per implementare le applicazioni .NET su AWS.

Le applicazioni serverless di solito comprendono una combinazione di funzioni Lambda e altri Servizi AWS gestiti che interagiscono per eseguire una particolare attività aziendale. AWS SAM e AWS CDK semplificano la creazione e l'implementazione di funzioni Lambda con altri Servizi AWS su larga scala. La [specifica del modello AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification.html) fornisce una sintassi semplice e chiara per descrivere le funzioni Lambda, le API, le autorizzazioni, le configurazioni e altre risorse AWS che costituiscono l'applicazione serverless. Con il [AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/home.html) si definisce l'infrastruttura cloud come codice per creare applicazioni affidabili, scalabili e convenienti nel cloud utilizzando linguaggi di programmazione e framework di programmazione moderni come .NET. Sia AWS CDK che AWS SAM utilizzano la CLI globale Lambda di .NET per creare pacchetti di funzioni.

Anche se è possibile utilizzare [livelli Lambda](chapter-layers.md) con funzioni in C\$1 [tramite la CLI di .NET Core](csharp-package-cli.md#csharp-layers), tale scelta non è preferibile. Le funzioni in C\$1 che utilizzano livelli caricano manualmente gli assembly condivisi in memoria durante il [Fase di init](lambda-runtime-environment.md#runtimes-lifecycle-ib), per cui i tempi di avvio a freddo possono aumentare. Includi invece tutto il codice condiviso in fase di compilazione per evitare che il caricamento degli assembly al runtime comprometta le prestazioni.

Nelle sezioni seguenti sono riportate le istruzioni per la creazione e l'implementazione di funzioni Lambda .NET tramite AWS SAM, il AWS CDK e la CLI globale di Lambda di .NET.

**Topics**
+ [

# Utilizzo della CLI globale Lambda di .NET
](csharp-package-cli.md)
+ [

# Implementazione di funzioni Lambda C\$1 tramite AWS SAM
](csharp-package-sam.md)
+ [

# Implementazione di funzioni Lambda C\$1 tramite AWS CDK
](csharp-package-cdk.md)
+ [

# Implementa applicazioni ASP.NET
](csharp-package-asp.md)

# Utilizzo della CLI globale Lambda di .NET
<a name="csharp-package-cli"></a>

La CLI .NET e l'estensione degli strumenti globali Lambda .NET (`Amazon.Lambda.Tools`) offrono un modo multi-piattaforma per creare applicazioni Lambda basate su .NET, impacchettarle e implementarle in Lambda. In questa sezione, scoprirai come creare nuovi progetti Lambda .NET utilizzando la CLI .NET e i modelli Amazon Lambda e come impacchettarli e implementarli tramite `Amazon.Lambda.Tools`

**Topics**
+ [

## Prerequisiti
](#csharp-package-cli-prerequisites)
+ [

## Creazione di progetti .NET con la CLI .NET
](#csharp-package-cli-create)
+ [

## Implementazione di progetti .NET con la CLI .NET
](#csharp-package-cli-deploy)
+ [

## Utilizzo dei livelli Lambda con la CLI di .NET
](#csharp-layers)

## Prerequisiti
<a name="csharp-package-cli-prerequisites"></a>

**SDK .NET 8**  
Se non l'hai già fatto, installa l'SDK [.NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) e Runtime.

**Modelli di progetto .NET di AWS Amazon.Lambda.Templates**  
Per generare il codice della funzione Lambda, usa il pacchetto [https://www.nuget.org/packages/Amazon.Lambda.Templates](https://www.nuget.org/packages/Amazon.Lambda.Templates) NuGet. Per installare questo pacchetto del modello, esegui il comando riportato:  

```
dotnet new install Amazon.Lambda.Templates
```

**Strumenti della CLI globale .NET AWSAmazon.Lambda.Tools**  
Per creare le funzioni Lambda, usa l'[estensione degli strumenti globali .NET](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/) [https://www.nuget.org/packages/Amazon.Lambda.Tools](https://www.nuget.org/packages/Amazon.Lambda.Tools). Per installare Amazon.Lambda.Tools, esegui il comando riportato:  

```
dotnet tool install -g Amazon.Lambda.Tools
```
Per ulteriori informazioni sull'estensione della CLI .NET Amazon.Lambda.Tools, consulta il repository [Estensioni AWS per la CLI .NET](https://github.com/aws/aws-extensions-for-dotnet-cli) su GitHub.

## Creazione di progetti .NET con la CLI .NET
<a name="csharp-package-cli-create"></a>

Nella CLI .NET, utilizzi il comando `dotnet new` per creare progetti .NET da una riga di comando. Lambda offre modelli aggiuntivi che utilizzano il pacchetto NuGet [https://www.nuget.org/packages/Amazon.Lambda.Templates](https://www.nuget.org/packages/Amazon.Lambda.Templates).

Dopo aver installato questo pacchetto, esegui il comando di seguito per visualizzare un elenco di modelli disponibili.

```
dotnet new list
```

Per esaminare i dettagli relativi a un modello, utilizzare l'opzione `help`. Ad esempio, per visualizzare i dettagli del modello `lambda.EmptyFunction`, emetti il seguente comando.

```
dotnet new lambda.EmptyFunction --help
```

Per creare un modello di base per una funzione Lambda .NET, usa il modello `lambda.EmptyFunction`. In questo modo viene creata una funzione semplice che accetta una stringa come input e la converte in lettere maiuscole utilizzando il metodo `ToUpper`. Questo modello supporta le seguenti opzioni: 
+ `--name`: il nome della funzione.
+ `--region`: la regione AWS in cui creare la funzione.
+ `--profile`: il nome di un profilo nel file delle credenziali AWS SDK per .NET. Per ulteriori informazioni sui profili di credenziali in .NET, consulta [Configurazione delle credenziali di AWS](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html) nella *Guida per gli sviluppatori di SDK AWS per .NET*.

In questo esempio, creiamo una nuova funzione vuota denominata `myDotnetFunction` utilizzando il profilo e le impostazioni di Regione AWS predefiniti:

```
dotnet new lambda.EmptyFunction --name myDotnetFunction
```

Questo comando crea i seguenti file e directory nella directory di progetto.

```
└── myDotnetFunction
    ├── src
    │   └── myDotnetFunction
    │       ├── Function.cs
    │       ├── Readme.md
    │       ├── aws-lambda-tools-defaults.json
    │       └── myDotnetFunction.csproj
    └── test
        └── myDotnetFunction.Tests
            ├── FunctionTest.cs
            └── myDotnetFunction.Tests.csproj
```

Nella directory `src/myDotnetFunction` esaminare i file seguenti:
+ **aws-lambda-tools-defaults.json**: file in cui si specificano le opzioni della riga di comando quando si distribuisce la funzione Lambda. Ad esempio:

  ```
    "profile" : "default",
    "region" : "us-east-2",
    "configuration" : "Release",
    "function-architecture": "x86_64",
    "function-runtime":"dotnet8",
    "function-memory-size" : 256,
    "function-timeout" : 30,
    "function-handler" : "myDotnetFunction::myDotnetFunction.Function::FunctionHandler"
  ```
+ **Function.cs**: codice della funzione del gestore Lambda. Si tratta di un modello C\$1 che include la libreria `Amazon.Lambda.Core` e un attributo `LambdaSerializer` predefiniti. Per ulteriori informazioni sui requisiti e sulle opzioni di serializzazione, consulta [Serializzazione nelle funzioni Lambda C\$1](csharp-handler.md#csharp-handler-serializer). Include anche una funzione di esempio che è possibile modificare per applicare il codice della funzione Lambda.

  ```
  using Amazon.Lambda.Core;
  
  // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
  [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
  
  namespace myDotnetFunction;
  
  public class Function
  {
  
      /// <summary>
      /// A simple function that takes a string and does a ToUpper
      /// </summary≫
      /// <param name="input"></param>
      /// <param name="context"></param>
      /// <returns></returns>
      public string FunctionHandler(string input, ILambdaContext context)
      {
          return input.ToUpper();
      }
  }
  ```
+ **myDotnetFunction.csproj**: un file [MSBuild](https://msdn.microsoft.com/en-us/library/dd393574.aspx) in cui sono elencati i file e gli assembly che costituiscono l'applicazione.

  ```
  <Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
      <TargetFramework>net8.0</TargetFramework>
      <ImplicitUsings>enable</ImplicitUsings>
      <Nullable>enable</Nullable>
      <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
      <AWSProjectType>Lambda</AWSProjectType>
      <!-- This property makes the build directory similar to a publish directory and helps the AWS .NET Lambda Mock Test Tool find project dependencies. -->
      <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
      <!-- Generate ready to run images during publishing to improve cold start time. -->
      <PublishReadyToRun>true</PublishReadyToRun>
    </PropertyGroup>
    <ItemGroup>
      <PackageReference Include="Amazon.Lambda.Core" Version="2.2.0" />
      <PackageReference Include="Amazon.Lambda.Serialization.SystemTextJson" Version="2.4.0" />
    </ItemGroup>
  </Project>
  ```
+ **Readme**: file che consente di documentare la funzione Lambda.

Nella directory `myfunction/test` esaminare i file seguenti:
+ **myDotnetFunction.Tests.csproj**: come indicato in precedenza, si tratta di un file [MSBuild](https://msdn.microsoft.com/en-us/library/dd393574.aspx) in cui sono elencati file e assembly che costituiscono il progetto di test. Si noti anche che nel file è inclusa la libreria `Amazon.Lambda.Core`, che consente di integrare in modo semplice qualsiasi modello Lambda necessario per eseguire il test della funzione.

  ```
  <Project Sdk="Microsoft.NET.Sdk">
     ... 
  
      <PackageReference Include="Amazon.Lambda.Core" Version="2.2.0 " />
     ...
  ```
+ **FunctionTest.cs**: lo stesso file di modello del codice C\$1 incluso nella directory `src`. Modificare questo file per eseguire il mirroring del codice di produzione della funzione e per eseguirne il test prima di caricare la funzione Lambda in un ambiente di produzione.

  ```
  using Xunit;
  using Amazon.Lambda.Core;
  using Amazon.Lambda.TestUtilities;
  
  using MyFunction;
  
  namespace MyFunction.Tests
  {
      public class FunctionTest
      {
          [Fact]
          public void TestToUpperFunction()
          {
  
              // Invoke the lambda function and confirm the string was upper cased.
              var function = new Function();
              var context = new TestLambdaContext();
              var upperCase = function.FunctionHandler("hello world", context);
  
              Assert.Equal("HELLO WORLD", upperCase);
          }
      }
  }
  ```

## Implementazione di progetti .NET con la CLI .NET
<a name="csharp-package-cli-deploy"></a>

Per creare il pacchetto di implementazione e implementarlo in Lambda, utilizzi gli strumenti della CLI `Amazon.Lambda.Tools`. Per implementare la funzione dai file creati nei passaggi precedenti, per prima cosa accedi alla cartella contenente il file `.csproj` della funzione.

```
cd myDotnetFunction/src/myDotnetFunction
```

Per implementare il codice in Lambda come pacchetto di implementazione .zip, emetti il comando seguente. Scegli il nome della tua funzione.

```
dotnet lambda deploy-function myDotnetFunction
```

Durante l'implementazione, la procedura guidata chiede di selezionare un [Definizione delle autorizzazioni della funzione Lambda con un ruolo di esecuzione](lambda-intro-execution-role.md). Per questo esempio, seleziona `lambda_basic_role`.

Dopo aver implementato la funzione, puoi testarla nel cloud con il comando `dotnet lambda invoke-function`. Per il codice di esempio nel modello `lambda.EmptyFunction`, puoi testare la tua funzione inserendo una stringa utilizzando l'opzione `--payload`.

```
dotnet lambda invoke-function myDotnetFunction --payload "Just checking if everything is OK"
```

Se la funzione è stata implementata con successo, dovresti vedere un output simile al seguente.

```
dotnet lambda invoke-function myDotnetFunction --payload "Just checking if everything is OK"
Amazon Lambda Tools for .NET Core applications (5.8.0)
Project Home: https://github.com/aws/aws-extensions-for-dotnet-cli, https://github.com/aws/aws-lambda-dotnet

Payload:
"JUST CHECKING IF EVERYTHING IS OK"

Log Tail:
START RequestId: id Version: $LATEST
END RequestId: id
REPORT RequestId: id  Duration: 0.99 ms       Billed Duration: 1 ms         Memory Size: 256 MB     Max Memory Used: 12 MB
```

## Utilizzo dei livelli Lambda con la CLI di .NET
<a name="csharp-layers"></a>

**Nota**  
Anche se è possibile utilizzare [livelli](chapter-layers.md) con funzioni in .NET, tale scelta non è preferibile. Le funzioni in .NET che utilizzano livelli caricano manualmente gli assembly condivisi in memoria durante la fase `Init`, per cui i tempi di avvio a freddo possono aumentare. Includi, invece, tutto il codice condiviso in fase di compilazione per sfruttare le ottimizzazioni integrate del compilatore .NET.

La CLI di .NET supporta comandi che facilitano la pubblicazione di livelli e l'implementazione di funzioni C\$1 che utilizzano livelli. Per pubblicare un livello in un bucket Amazon S3 specificato, utilizza il comando seguente nella stessa directory del tuo file `.csproj`:

```
dotnet lambda publish-layer <layer_name> --layer-type runtime-package-store --s3-bucket <s3_bucket_name>
```

Quando implementi la funzione utilizzando la CLI di .NET, quindi, specifica l'ARN utilizzato dal livello nel seguente comando:

```
dotnet lambda deploy-function <function_name> --function-layers arn:aws:lambda:us-east-1:123456789012:layer:layer-name:1
```

Per un esempio completo di una funzione Hello World, consulta l'esempio [blank-csharp-with-layer](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-csharp-with-layer).

# Implementazione di funzioni Lambda C\$1 tramite AWS SAM
<a name="csharp-package-sam"></a>

AWS Serverless Application Model (AWS SAM) è un toolkit che aiuta a semplificare il processo di creazione ed esecuzione di applicazioni serverless su AWS. Definisci le risorse per la tua applicazione in un modello YAML o JSON e usa l'interfaccia della linea di comando AWS SAM (AWS SAM CLI) per compilare, creare pacchetti e implementare le tue applicazioni. Quando crei una funzione Lambda da un modello AWS SAM, AWS SAM crea automaticamente un pacchetto di implementazione .zip o un'immagine di container con il codice della funzione e le dipendenze specificate.AWS SAM quindi implementa la funzione utilizzando uno [stack CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacks.html). Per ulteriori informazioni sull'utilizzo di AWS SAM per creare e implementare funzioni Lambda, consulta la pagina [Nozioni di base su AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started.html) nella *Guida introduttiva per gli sviluppatori di AWS Serverless Application Model*.

La seguente procedura mostra come scaricare, creare e implementare un'applicazione Hello World .NET di esempio con AWS SAM. Questa applicazione di esempio utilizza una funzione Lambda e un endpoint Gateway Amazon API per implementare un backend API di base. Quando invii una richiesta HTTP GET all'endpoint Gateway API, Gateway API richiama la funzione Lambda. La funzione restituisce un messaggio "hello world", insieme all'indirizzo IP dell'istanza della funzione Lambda che elabora la richiesta.

Quando crei e implementi l'applicazione utilizzando AWS SAM, dietro le quinte, la CLI AWS SAM utilizza il comando `dotnet lambda package` per impacchettare i singoli bundle di codici delle funzioni Lambda.

## Prerequisiti
<a name="csharp-package-sam-prerequisites"></a>

**SDK .NET 8**  
Installa l'SDK [.NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) e Runtime.

**CLI AWS SAM versione 1.39 o successiva**  
Per informazioni su come installare l'ultima versione della CLI AWS SAM, consulta [Installazione della CLI AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html).

## Implementare un'applicazione AWS SAM di esempio
<a name="csharp-package-sam-deploy"></a>

1. Inizializza l'applicazione utilizzando il modello .NET Hello world con il comando riportato di seguito.

   ```
   sam init --app-template hello-world --name sam-app \
   --package-type Zip --runtime dotnet8
   ```

   Questo comando crea i seguenti file e directory nella directory di progetto.

   ```
   └── sam-app
       ├── README.md
       ├── events
       │   └── event.json
       ├── omnisharp.json
       ├── samconfig.toml
       ├── src
       │   └── HelloWorld
       │       ├── Function.cs
       │       ├── HelloWorld.csproj
       │       └── aws-lambda-tools-defaults.json
       ├── template.yaml
       └── test
           └── HelloWorld.Test
               ├── FunctionTest.cs
               └── HelloWorld.Tests.csproj
   ```

1. Passa alla directory contenente il `template.yaml file`. Questo file è un modello che definisce le risorse AWS per l'applicazione, tra cui la funzione Lambda e un'API di Gateway API.

   ```
   cd sam-app
   ```

1. Per creare il codice sorgente dell'applicazione, digita il comando riportato di seguito.

   ```
   sam build
   ```

1. Per implementare l'applicazione su AWS, emetti il comando riportato di seguito:

   ```
   sam deploy --guided
   ```

   Questo comando impacchetta e implementa l'applicazione con la seguente serie di prompt. Per accettare le opzioni predefinite, premi Invio.
**Nota**  
Per **HelloWorldFunction potrebbe non avere l'autorizzazione definita, va bene?**, assicurati di inserire `y`.
   + **Nome dello stack**: il nome dello stack da implementare su CloudFormation. Questo nome deve essere univoco per l'Account AWS e la Regione AWS.
   + **Regione AWS**: la Regione AWS in cui desideri implementare l'app.
   + **Conferma le modifiche prima dell'implementazione**: seleziona Sì per rivedere manualmente tutti i set di modifiche prima che AWS SAM implementi modifiche all'applicazione. Selezionando No, la CLI AWS SAM implementa automaticamente le modifiche alle applicazioni.
   + **Consenti la creazione di ruoli IAM per la CLI SAM**: numerosi modelli AWS SAM, incluso quello Hello world in questo esempio, creano ruoli AWS Identity and Access Management (IAM) per consentire alle funzioni Lambda di accedere ad altri Servizi AWS. Seleziona Sì per fornire l'autorizzazione a distribuire uno stack CloudFormation che crea o modifica i ruoli IAM.
   + **Disabilita il rollback**: per impostazione predefinita, se AWS SAM riporta un errore durante la creazione o l'implementazione dello stack, lo stack torna alla versione precedente. Seleziona No per accettare questa impostazione predefinita.
   + Per **HelloWorldFunction potrebbe non avere l'autorizzazione definita, va bene?**, immetti `y`.
   + **Salva gli argomenti in samconfig.toml**: seleziona Sì per salvare le tue scelte di configurazione. In futuro, potrai eseguire nuovamente `sam deploy` senza parametri per implementare le modifiche all'applicazione.

1. Una volta completata l'implementazione dell'applicazione, la CLI restituisce il nome della risorsa Amazon (ARN) della funzione Lambda Hello World e il ruolo IAM creato per essa. Consente inoltre di visualizzare anche l'endpoint dell'API di Gateway API. Per testare l'applicazione, apri l'endpoint in un browser. Si avrà una risposta simile alla seguente.

   ```
   {"message":"hello world","location":"34.244.135.203"}
   ```

1. Per eliminare le risorse, emetti il seguente comando. Tieni presente che l'endpoint dell'API che hai creato è un endpoint pubblico accessibile su Internet. È consigliabile eliminare questo endpoint dopo il test.

   ```
   sam delete
   ```

## Passaggi successivi
<a name="csharp-package-sam-next"></a>

Per ulteriori informazioni su come utilizzare AWS SAM per creare e implementare le funzioni Lambda con .NET, consulta le seguenti risorse:
+ La [https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html)
+ [Creazione di applicazioni .NET serverless con AWS Lambda e la CLI SAM](https://aws.amazon.com/blogs/dotnet/building-serverless-net-applications-with-aws-lambda-and-the-sam-cli/)

# Implementazione di funzioni Lambda C\$1 tramite AWS CDK
<a name="csharp-package-cdk"></a>

AWS Cloud Development Kit (AWS CDK) è un framework di sviluppo software open source per definire l'infrastruttura cloud come codice con linguaggi di programmazione e framework di programmazione moderni come .NET. I progetti AWS CDK vengono eseguiti per generare modelli CloudFormation che vengono poi utilizzati per implementare il codice.

Per creare e implementare un'applicazione .NET Hello world di esempio utilizzando ilAWS CDK, segui le istruzioni nelle sezioni seguenti. L'applicazione di esempio implementa un backend di API di base che consiste di un endpoint Gateway API e di una funzione Lambda. Quando si invia una richiesta HTTP GET all'endpoint, Gateway API richiama la funzione Lambda. La funzione restituisce un messaggio "hello world", insieme all'indirizzo IP dell'istanza Lambda che elabora la richiesta.

## Prerequisiti
<a name="csharp-package-cdk-prereqs"></a>

**SDK .NET 8**  
Installa l'SDK [.NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) e Runtime.

**AWS CDK versione 2**  
Per informazioni su come installare la versione più recente di AWS CDK, consulta la [Nozioni di base sul AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html) nella *Guida per gli sviluppatori di AWS Cloud Development Kit (AWS CDK) v2*.

## Implementare un'applicazione AWS CDK di esempio
<a name="csharp-package-cdk-deploy"></a>

1. Crea una directory di progetto per l'applicazione di esempio e passa ad essa.

   ```
   mkdir hello-world
   cd hello-world
   ```

1. Inizializza una nuova applicazione AWS CDK eseguendo il comando riportato di seguito.

   ```
   cdk init app --language csharp
   ```

   Questo comando crea i seguenti file e directory nella directory di progetto.

   ```
   ├── README.md
   ├── cdk.json
   └── src
       ├── HelloWorld
       │   ├── GlobalSuppressions.cs
       │   ├── HelloWorld.csproj
       │   ├── HelloWorldStack.cs
       │   └── Program.cs
       └── HelloWorld.sln
   ```

1. Apri la directory `src` e crea una nuova funzione Lambda utilizzando la CLI .NET. Questa è la funzione che implementerai utilizzando il AWS CDK. In questo esempio, viene creata una funzione Hello world denominata `HelloWorldLambda` utilizzando il modello `lambda.EmptyFunction`.

   ```
   cd src
   dotnet new lambda.EmptyFunction -n HelloWorldLambda
   ```

   Dopo questo passaggio, la struttura di directory all'interno della directory del progetto dovrebbe avere un aspetto simile al seguente.

   ```
   ├── README.md
   ├── cdk.json
   └── src
       ├── HelloWorld
       │   ├── GlobalSuppressions.cs
       │   ├── HelloWorld.csproj
       │   ├── HelloWorldStack.cs
       │   └── Program.cs
       ├── HelloWorld.sln
       └── HelloWorldLambda
           ├── src
           │   └── HelloWorldLambda
           │       ├── Function.cs
           │       ├── HelloWorldLambda.csproj
           │       ├── Readme.md
           │       └── aws-lambda-tools-defaults.json
           └── test
               └── HelloWorldLambda.Tests
                   ├── FunctionTest.cs
                   └── HelloWorldLambda.Tests.csproj
   ```

1. Apri il file `HelloWorldStack.cs` nella directory `src/HelloWorld`. Sostituisci il contenuto del file con il seguente codice.

   ```
   using Amazon.CDK;
   using Amazon.CDK.AWS.Lambda;
   using Amazon.CDK.AWS.Logs;
   using Constructs;
   
   namespace CdkTest
   {
       public class HelloWorldStack : Stack
       {
           internal HelloWorldStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props)
           {
               var buildOption = new BundlingOptions()
               {
                   Image = Runtime.DOTNET_8.BundlingImage,
                   User = "root",
                   OutputType = BundlingOutput.ARCHIVED,
                   Command = new string[]{
               "/bin/sh",
                   "-c",
                   " dotnet tool install -g Amazon.Lambda.Tools"+
                   " && dotnet build"+
                   " && dotnet lambda package --output-package /asset-output/function.zip"
                   }
               };
   
                var helloWorldLambdaFunction = new Function(this, "HelloWorldFunction", new FunctionProps
               {
                   Runtime = Runtime.DOTNET_8,
                   MemorySize = 1024,
                   LogRetention = RetentionDays.ONE_DAY,
                   Handler = "HelloWorldLambda::HelloWorldLambda.Function::FunctionHandler",
                   Code = Code.FromAsset("./src/HelloWorldLambda/src/HelloWorldLambda", new Amazon.CDK.AWS.S3.Assets.AssetOptions
                   {
                       Bundling = buildOption
                   }),
               });
           }
       }
   }
   ```

   Questo è il codice per compilare e raggruppare il codice dell'applicazione, nonché la definizione della funzione Lambda stessa. L'oggetto `BundlingOptions` consente di creare un file zip, insieme a una serie di comandi utilizzati per generare il contenuto del file zip. In questa istanza, il comando `dotnet lambda package` viene utilizzato per compilare e generare il file zip.

1. Per implementare l'applicazione, emetti il comando riportato di seguito.

   ```
   cdk deploy
   ```

1. Invoca la funzione Lambda implementata utilizzando la CLI .NET Lambda.

   ```
   dotnet lambda invoke-function HelloWorldFunction -p "hello world"
   ```

1. Una volta terminato il test, potrai eliminare le risorse create (a meno che non si desideri mantenerle). Per eliminare le risorse, emetti il seguente comando.

   ```
   cdk destroy
   ```

## Passaggi successivi
<a name="csharp-package-cdk-next"></a>

Per ulteriori informazioni su come utilizzare AWS CDK per creare e implementare le funzioni Lambda con .NET, consulta le seguenti risorse:
+ [Operazioni con il CDK AWS in C\$1](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-csharp.html)
+ [Crea, impacchetta e pubblica funzioni Lambda C\$1 .NET CDK AWS](https://aws.amazon.com/blogs/modernizing-with-aws/build-package-publish-dotnet-csharp-lambda-functions-aws-cdk/)

# Implementa applicazioni ASP.NET
<a name="csharp-package-asp"></a>

Oltre a ospitare funzioni basate sugli eventi, puoi utilizzare .NET con Lambda anche per ospitare applicazioni ASP.NET leggere. Puoi creare e implementare applicazioni ASP.NET utilizzando il pacchetto `Amazon.Lambda.AspNetCoreServer` NuGet. In questa sezione, imparerai come distribuire un'API Web ASP.NET in Lambda utilizzando gli strumenti della CLI .NET Lambda.

**Topics**
+ [

## Prerequisiti
](#csharp-package-asp-prerequisites)
+ [

## Implementazione di un'API Web ASP.NET in Lambda
](#csharp-package-asp-deploy-api)
+ [

## Implementazione di API minime ASP.NET su Lambda
](#csharp-package-asp-deploy-minimal)

## Prerequisiti
<a name="csharp-package-asp-prerequisites"></a>

**SDK .NET 8**  
Installa l'SDK [.NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) e ASP.NET Core Runtime.

**Amazon.Lambda.Tools**  
Per creare le funzioni Lambda, usa l'[estensione degli strumenti globali .NET](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/) [https://www.nuget.org/packages/Amazon.Lambda.Tools](https://www.nuget.org/packages/Amazon.Lambda.Tools). Per installare Amazon.Lambda.Tools, esegui il comando riportato:  

```
dotnet tool install -g Amazon.Lambda.Tools
```
Per ulteriori informazioni sull'estensione della CLI .NET Amazon.Lambda.Tools, consulta il repository [Estensioni AWS per la CLI .NET](https://github.com/aws/aws-extensions-for-dotnet-cli) su GitHub.

**Amazon.Lambda.Templates**  
Per generare il codice della funzione Lambda, usa il pacchetto [https://www.nuget.org/packages/Amazon.Lambda.Templates](https://www.nuget.org/packages/Amazon.Lambda.Templates) NuGet. Per installare questo pacchetto del modello, esegui il comando riportato:  

```
dotnet new --install Amazon.Lambda.Templates
```

## Implementazione di un'API Web ASP.NET in Lambda
<a name="csharp-package-asp-deploy-api"></a>

Per implementare un'API Web utilizzando ASP.NET, puoi utilizzare i modelli Lambda .NET per creare un nuovo progetto di API Web. Utilizza il comando seguente per inizializzare un nuovo progetto di API Web ASP.NET. Nel comando di esempio, diamo un nome al progetto `AspNetOnLambda`.

```
dotnet new serverless.AspNetCoreWebAPI -n AspNetOnLambda
```

Questo comando crea i seguenti file e directory nella directory di progetto.

```
.
└── AspNetOnLambda
    ├── src
    │   └── AspNetOnLambda
    │       ├── AspNetOnLambda.csproj
    │       ├── Controllers
    │       │   └── ValuesController.cs
    │       ├── LambdaEntryPoint.cs
    │       ├── LocalEntryPoint.cs
    │       ├── Readme.md
    │       ├── Startup.cs
    │       ├── appsettings.Development.json
    │       ├── appsettings.json
    │       ├── aws-lambda-tools-defaults.json
    │       └── serverless.template
    └── test
        └── AspNetOnLambda.Tests
            ├── AspNetOnLambda.Tests.csproj
            ├── SampleRequests
            │   └── ValuesController-Get.json
            ├── ValuesControllerTests.cs
            └── appsettings.json
```

Quando Lambda richiama la funzione, il punto di ingresso che utilizza è il file `LambdaEntryPoint.cs`. Il file creato dal modello Lambda .NET contiene il seguente codice.

```
namespace AspNetOnLambda;

public class LambdaEntryPoint : Amazon.Lambda.AspNetCoreServer.APIGatewayProxyFunction
{
    protected override void Init(IWebHostBuilder builder)
    {
        builder
            .UseStartup≪Startup≫();
    }

    protected override void Init(IHostBuilder builder)
    {
    }
}
```

Il punto di ingresso utilizzato da Lambda deve ereditare da una delle tre classi base del pacchetto `Amazon.Lambda.AspNetCoreServer`. Queste tre classi base sono:
+ `APIGatewayProxyFunction`
+ `APIGatewayHttpApiV2ProxyFunction`
+ `ApplicationLoadBalancerFunction`

La classe predefinita utilizzata quando si crea il file `LambdaEntryPoint.cs` utilizzando il modello Lambda .NET fornito è `APIGatewayProxyFunction`. La classe base che usi nella tua funzione dipende dal livello API che precede la tua funzione Lambda.

Ciascuna delle tre classi base contiene un metodo pubblico denominato `FunctionHandlerAsync`. Il nome di questo metodo farà parte della [stringa del gestore](csharp-handler.md#csharp-class-library-handlers) che Lambda usa per richiamare la tua funzione. Il metodo `FunctionHandlerAsync` trasforma il payload dell'evento in entrata nel formato ASP.NET corretto e la risposta ASP.NET in un payload di risposta Lambda. Per il progetto `AspNetOnLambda` di esempio mostrato, la stringa del gestore sarebbe la seguente.

```
AspNetOnLambda::AspNetOnLambda.LambdaEntryPoint::FunctionHandlerAsync
```

Per implementare l'API in Lambda, emetti i seguenti comandi per navigare nella directory contenente il file del codice sorgente e implementa la funzione utilizzando CloudFormation.

```
cd AspNetOnLambda/src/AspNetOnLambda
dotnet lambda deploy-serverless
```

**Suggerimento**  
Quando implementi un'API utilizzando il comando `dotnet lambda deploy-serverless`, CloudFormation assegna alla funzione Lambda un nome basato sul nome dello stack specificato durante l'implementazione. Per assegnare un nome personalizzato alla funzione Lambda, modifica il file `serverless.template` in modo da aggiungere una proprietà `FunctionName` alla risorsa `AWS::Serverless::Function`. Consulta [Tipo di nome](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-name.html) nella *Guida per l'utente di CloudFormation* per ulteriori informazioni.

## Implementazione di API minime ASP.NET su Lambda
<a name="csharp-package-asp-deploy-minimal"></a>

Per implementare un'API minima ASP.NET, puoi utilizzare i modelli Lambda .NET per creare un nuovo progetto di API minima. Utilizza il comando seguente per inizializzare un nuovo progetto di API minima ASP.NET. In questo esempio, al progetto assegnamo il nome `MinimalApiOnLambda`.

```
dotnet new serverless.AspNetCoreMinimalAPI -n MinimalApiOnLambda
```

Questo comando crea i seguenti file e directory nella directory di progetto.

```
└── MinimalApiOnLambda
    └── src
        └── MinimalApiOnLambda
            ├── Controllers
            │   └── CalculatorController.cs
            ├── MinimalApiOnLambda.csproj
            ├── Program.cs
            ├── Readme.md
            ├── appsettings.Development.json
            ├── appsettings.json
            ├── aws-lambda-tools-defaults.json
            └── serverless.template
```

Il file `Program.cs` contiene il seguente codice.

```
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();

// Add AWS Lambda support. When application is run in Lambda Kestrel is swapped out as the web server with Amazon.Lambda.AspNetCoreServer. This
// package will act as the webserver translating request and responses between the Lambda event source and ASP.NET Core.
builder.Services.AddAWSLambdaHosting(LambdaEventSource.RestApi);

var app = builder.Build();


app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.MapGet("/", () => "Welcome to running ASP.NET Core Minimal API on AWS Lambda");

app.Run();
```

Per configurare l'API minima da eseguire su Lambda, potrebbe essere necessario modificare questo codice in modo che le richieste e le risposte tra Lambda e ASP.NET Core vengano tradotte correttamente. Per impostazione predefinita, la funzione è configurata per un'origine di eventi della REST API. Per un'API HTTP o un Application Load Balancer, sostituisci `(LambdaEventSource.RestApi)` con una delle seguenti opzioni:
+ `(LambdaEventSource.HttpAPi)`
+ `(LambdaEventSource.ApplicationLoadBalancer)`

Per implementare l'API minima in Lambda, emetti i seguenti comandi per navigare nella directory contenente il file del codice sorgente e implementa la funzione utilizzando CloudFormation.

```
cd MinimalApiOnLambda/src/MinimalApiOnLambda
dotnet lambda deploy-serverless
```

# Utilizzo dei livelli per le funzioni Lambda .NET
<a name="dotnet-layers"></a>

Consigliamo di non utilizzare i [livelli](chapter-layers.md) per gestire le dipendenze per le funzioni Lambda scritte in .NET. Il motivo è che .NET è un linguaggio compilato, e le funzioni devono comunque caricare manualmente gli assembly condivisi in memoria durante la fase di [inizializzazione](lambda-runtime-environment.md#runtimes-lifecycle-ib), per cui i tempi di avvio a freddo possono aumentare. L'uso dei livelli non solo complica il processo di implementazione, ma impedisce anche di sfruttare le ottimizzazioni integrate del compilatore.

Per utilizzare dipendenze esterne con i gestori .NET, includile direttamente nel pacchetto di implementazione durante la fase di compilazione. In questo modo, semplifichi il processo di implementazione e sfrutti anche le ottimizzazioni integrate del compilatore .NET. Per un esempio di come importare e utilizzare dipendenze come pacchetti NuGet nella tua funzione, consulta [Definire l'handler della funzione Lambda in C\$1](csharp-handler.md).

# Distribuzione delle funzioni .NET Lambda con immagini di container
<a name="csharp-image"></a>

Esistono tre modi per creare un'immagine di container per una funzione Lambda in .NET:
+ [Utilizzo di un'immagine AWS di base per.NET](#csharp-image-instructions)

  [Le immagini di base AWS](images-create.md#runtimes-images-lp) sono precaricate con un runtime in linguaggio, un client di interfaccia di runtime per gestire l'interazione tra Lambda e il codice della funzione e un emulatore di interfaccia di runtime per i test locali.
+ [Utilizzo di un'immagine di AWS base solo per il sistema operativo](images-create.md#runtimes-images-provided)

  [AWS Le immagini di base solo](https://gallery.ecr.aws/lambda/provided) per il sistema operativo contengono una distribuzione Amazon Linux e l'emulatore [di interfaccia di runtime](https://github.com/aws/aws-lambda-runtime-interface-emulator/). Queste immagini vengono comunemente utilizzate per creare immagini di container per linguaggi compilati, come [Go](go-image.md#go-image-provided) e [Rust](lambda-rust.md), e per un linguaggio o una versione di linguaggio per cui Lambda non fornisce un'immagine di base, come Node.js 19. Puoi anche utilizzare immagini di base solo per il sistema operativo al fine di implementare un [runtime personalizzato](runtimes-custom.md). Per rendere l'immagine compatibile con Lambda, devi includere il [client di interfaccia di runtime per .NET](#csharp-image-clients) nell'immagine.
+ [Utilizzo AWS di un'immagine non di base](#csharp-image-clients)

  È possibile utilizzare un'immagine di base alternativa da un altro registro del container, come ad esempio Alpine Linux o Debian. Puoi anche utilizzare un'immagine personalizzata creata dalla tua organizzazione. Per rendere l'immagine compatibile con Lambda, devi includere il [client di interfaccia di runtime per .NET](#csharp-image-clients) nell'immagine.

**Suggerimento**  
Per ridurre il tempo necessario all'attivazione delle funzioni del container Lambda, consulta [Utilizzo di compilazioni a più fasi](https://docs.docker.com/build/building/multi-stage/) nella documentazione Docker. Per creare immagini di container efficienti, segui le [best practice per scrivere file Docker](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/).

Questa pagina spiega come creare, testare e implementare le immagini di container per Lambda.

**Topics**
+ [

## AWS immagini di base per.NET
](#csharp-image-base)
+ [

## Utilizzo di un'immagine AWS di base per.NET
](#csharp-image-instructions)
+ [

## Utilizzo di un'immagine di base alternativa con il client di interfaccia di runtime
](#csharp-image-clients)

## AWS immagini di base per.NET
<a name="csharp-image-base"></a>

AWS fornisce le seguenti immagini di base per.NET:


| Tag | Runtime | Sistema operativo | Dockerfile | Raggiunta obsolescenza | 
| --- | --- | --- | --- | --- | 
| 10 | .NET 10 | Amazon Linux 2023 | [Dockerfile per.NET 10 su GitHub](https://github.com/aws/aws-lambda-base-images/blob/dotnet10/Dockerfile.dotnet10) |   14 novembre 2028   | 
| 9 | .NET 9 | Amazon Linux 2023 | [Dockerfile per.NET 9 su GitHub](https://github.com/aws/aws-lambda-base-images/blob/dotnet9/Dockerfile.dotnet9) |   10 novembre 2026   | 
| 8 | .NET 8 | Amazon Linux 2023 | [Dockerfile per.NET 8 su GitHub](https://github.com/aws/aws-lambda-base-images/blob/dotnet8/Dockerfile.dotnet8) |   10 novembre 2026   | 

[Archivio Amazon ECR: gallery.ecr. aws/lambda/dotnet](https://gallery.ecr.aws/lambda/dotnet)

## Utilizzo di un'immagine AWS di base per.NET
<a name="csharp-image-instructions"></a>

### Prerequisiti
<a name="dotnet-csharp-image-prerequisites"></a>

Per completare le fasi riportate in questa sezione, è necessario:
+ [SDK .NET](https://dotnet.microsoft.com/download): i passaggi seguenti utilizzano l'immagine di base .NET 8. Assicurati che la tua versione di .NET corrisponda alla versione dell'[immagine di base](https://gallery.ecr.aws/lambda/dotnet) specificata nel tuo Dockerfile.
+ [Docker](https://docs.docker.com/get-docker) (versione minima 25.0.0)
+ Il [plugin buildx](https://github.com/docker/buildx/blob/master/README.md) di Docker.

### Creazione e implementazione di un'immagine utilizzando un'immagine di base
<a name="dotnet-image-create"></a>

Nei passaggi seguenti, utilizzerai [Amazon.Lambda.Templates](https://github.com/aws/aws-lambda-dotnet#dotnet-cli-templates) e [Amazon.Lambda.Tools](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) per creare un progetto .NET. Quindi, crei un'immagine Docker, carichi l'immagine su Amazon ECR e la implementi su una funzione Lambda.

1. Installa il pacchetto [Amazon.Lambda.Templates.](https://github.com/aws/aws-lambda-dotnet#dotnet-cli-templates) NuGet 

   ```
   dotnet new install Amazon.Lambda.Templates
   ```

1. Crea un progetto .NET utilizzando il modello `lambda.image.EmptyFunction`.

   ```
   dotnet new lambda.image.EmptyFunction --name MyFunction --region us-east-1
   ```

   I file di progetto sono archiviati nella directory `MyFunction/src/MyFunction`:
   + **aws-lambda-tools-defaults.json**: specifica le opzioni della riga di comando per la distribuzione della funzione Lambda.
   + **Function.cs**: codice della funzione del gestore Lambda. Si tratta di un modello C\$1 che include la libreria `Amazon.Lambda.Core` e un attributo `LambdaSerializer` predefiniti. Per ulteriori informazioni sui requisiti e sulle opzioni di serializzazione, consulta la pagina [Serializzazione nelle funzioni Lambda C\$1](csharp-handler.md#csharp-handler-serializer). A fini di test, puoi utilizzare il codice fornito o sostituirlo con il tuo codice personalizzato.
   + **MyFunction.csproj**: un file di [progetto.NET, che elenca i file](https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview#project-files) e gli assembly che compongono l'applicazione.
   + **Dockerfile**: a fini di test, puoi utilizzare il Dockerfile fornito o sostituirlo con un file personalizzato. Se utilizzi un file personalizzato, assicurati di:
     + Imposta la proprietà `FROM` sull'[URI dell'immagine di base](https://gallery.ecr.aws/lambda/dotnet). L'immagine di base e la `TargetFramework` nel file `MyFunction.csproj` devono utilizzare entrambe la stessa versione di .NET. Ad esempio, per utilizzare .NET 9:
       + File Docker: `FROM public.ecr.aws/lambda/dotnet:9`
       + MyFunction.csproj: `<TargetFramework>net9.0</TargetFramework>`
     + Imposta l'argomento `CMD` specificando il gestore della funzione Lambda. Questo dovrebbe corrispondere a `image-command` in `aws-lambda-tools-defaults.json`.

1. Installa lo [strumento globale .NET](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/) Amazon.Lambda.Tools.

   ```
   dotnet tool install -g Amazon.Lambda.Tools
   ```

   Se Amazon.Lambda.Tools è già installato, assicurati di disporre della versione più recente.

   ```
   dotnet tool update -g Amazon.Lambda.Tools
   ```

1. Passa alla directory `MyFunction/src/MyFunction`, se non lo hai ancora fatto.

   ```
   cd src/MyFunction
   ```

1. Utilizza Amazon.Lambda.Tools per creare l'immagine Docker, trasferirla in un nuovo repository Amazon ECR e implementare la funzione Lambda.

   Per `--function-role`, specifica il nome del ruolo, non il nome della risorsa Amazon (ARN), del [ruolo di esecuzione](lambda-intro-execution-role.md) della funzione. Ad esempio, `lambda-role`.

   ```
   dotnet lambda deploy-function MyFunction --function-role lambda-role
   ```

   Per ulteriori informazioni sullo strumento globale Amazon.Lambda.Tools, consulta l'archivio Extensions [AWS for](https://github.com/aws/aws-extensions-for-dotnet-cli) .NET CLI su. GitHub

1. Richiama la funzione.

   ```
   dotnet lambda invoke-function MyFunction --payload "Testing the function"
   ```

   in caso di esito positivo, vedrai una risposta simile alla seguente:

   ```
   Payload:
   {"Lower":"testing the function","Upper":"TESTING THE FUNCTION"}
   
   Log Tail:
   INIT_REPORT Init Duration: 9999.81 ms   Phase: init     Status: timeout
   START RequestId: 12378346-f302-419b-b1f2-deaa1e8423ed Version: $LATEST
   END RequestId: 12378346-f302-419b-b1f2-deaa1e8423ed
   REPORT RequestId: 12378346-f302-419b-b1f2-deaa1e8423ed  Duration: 3173.06 ms    Billed Duration: 3174 ms        Memory Size: 512 MB     Max Memory Used: 24 MB
   ```

1. Elimina la funzione Lambda.

   ```
   dotnet lambda delete-function MyFunction
   ```

## Utilizzo di un'immagine di base alternativa con il client di interfaccia di runtime
<a name="csharp-image-clients"></a>

Se utilizzi un'[immagine di base solo per il sistema operativo](images-create.md#runtimes-images-provided) o un'immagine di base alternativa, devi includere il client dell'interfaccia di runtime nell'immagine. Il client dell'interfaccia di runtime estende l'[API Runtime](runtimes-api.md), che gestisce l'interazione tra Lambda e il codice della funzione.

L'esempio seguente mostra come creare un'immagine contenitore per.NET utilizzando un'immagine non di AWS base e come aggiungere [Amazon.Lambda. RuntimeSupport ](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.RuntimeSupport/README.md#using-amazonlambdaruntimesupport-as-a-class-library)pacchetto, che è il client dell'interfaccia di runtime Lambda per .NET. Il Dockerfile di esempio utilizza l'immagine di base Microsoft .NET 8.

### Prerequisiti
<a name="dotnet-csharp-alt-prerequisites"></a>

Per completare le fasi riportate in questa sezione, è necessario:
+ [.NET SDK](https://dotnet.microsoft.com/download): i passaggi seguenti utilizzano un'immagine di base.NET 9. Assicurati che la tua versione di .NET corrisponda alla versione dell'immagine di base specificata nel tuo Dockerfile.
+ [Docker](https://docs.docker.com/get-docker) (versione minima 25.0.0)
+ Il [plugin buildx](https://github.com/docker/buildx/blob/master/README.md) di Docker.

### Creazione e implementazione di un'immagine utilizzando un'immagine di base alternativa
<a name="dotnet-alt-create"></a>

1. Installa il pacchetto [ NuGet Amazon.Lambda.Templates](https://github.com/aws/aws-lambda-dotnet#dotnet-cli-templates).

   ```
   dotnet new install Amazon.Lambda.Templates
   ```

1. Crea un progetto .NET utilizzando il modello `lambda.CustomRuntimeFunction`. [Questo modello include Amazon.Lambda. RuntimeSupport](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.RuntimeSupport/README.md#using-amazonlambdaruntimesupport-as-a-class-library)pacchetto.

   ```
   dotnet new lambda.CustomRuntimeFunction --name MyFunction --region us-east-1
   ```

1. Passa alla directory `MyFunction/src/MyFunction`. Qui sono archiviati i file del progetto. Esamina i seguenti file di log:
   + **aws-lambda-tools-defaults.json**: in questo file si specificano le opzioni della riga di comando quando si distribuisce la funzione Lambda.
   + **Function.cs**: il codice contiene una classe con un metodo `Main` che inizializza la libreria `Amazon.Lambda.RuntimeSupport` come bootstrap. Il metodo `Main` sarà il punto di ingresso per il processo della funzione. Il metodo `Main` racchiude il gestore della funzione in un wrapper con cui il bootstrap può funzionare. [Per ulteriori informazioni, consulta Using Amazon.Lambda. RuntimeSupport come libreria di classi](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.RuntimeSupport/README.md#using-amazonlambdaruntimesupport-as-a-class-library) nel repository. GitHub 
   + **MyFunction.csproj** — Un file di [progetto.NET, che elenca i file](https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview#project-files) e gli assembly che compongono l'applicazione.
   + **Readme.md**: questo file contiene ulteriori informazioni sulla funzione Lambda di esempio.

1. Apri il file `aws-lambda-tools-defaults.json` e aggiungi le righe seguenti.

   ```
     "package-type": "image",
     "docker-host-build-output-dir": "./bin/Release/lambda-publish"
   ```
   + **package-type**: definisce il pacchetto di implementazione come immagine di container.
   + **docker-host-build-output-dir**: imposta la directory di output per il processo di compilazione.  
**Example aws-lambda-tools-defaults.json**  

   ```
   {
     "Information": [
       "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.",
       "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.",
       "dotnet lambda help",
       "All the command line options for the Lambda command can be specified in this file."
     ],
     "profile": "",
     "region": "us-east-1",
     "configuration": "Release",
     "function-runtime": "provided.al2023",
     "function-memory-size": 256,
     "function-timeout": 30,
     "function-handler": "bootstrap",
     "msbuild-parameters": "--self-contained true",
     "package-type": "image",
     "docker-host-build-output-dir": "./bin/Release/lambda-publish"
   }
   ```

1. Crea un Dockerfile nella directory `MyFunction/src/MyFunction`. Il seguente Dockerfile di esempio utilizza un'immagine di base Microsoft .NET anziché un'[immagine di base AWS](#csharp-image-base).
   + Imposta la proprietà `FROM` sull'identificativo dell'immagine di base. L'immagine di base e la `TargetFramework` nel file `MyFunction.csproj` devono utilizzare entrambe la stessa versione di .NET.
   + Utilizza il comando `COPY` per copiare la funzione nella directory `/var/task`.
   + Imposta l'`ENTRYPOINT` sul modulo su cui desideri che il container Docker venga eseguito all'avvio. In questo caso, il modulo è il bootstrap, che inizializza la libreria `Amazon.Lambda.RuntimeSupport`.

   Nota che l'esempio Dockerfile non include un'[istruzione USER](https://docs.docker.com/reference/dockerfile/#user). Quando implementi un'immagine di container su Lambda, Lambda definisce automaticamente un utente Linux predefinito con autorizzazioni con privilegi minimi. Questo è diverso dal comportamento standard di Docker, che per impostazione predefinita è l'utente `root` quando non viene fornita alcuna istruzione `USER`.  
**Example Dockerfile**  

   ```
   # You can also pull these images from DockerHub amazon/aws-lambda-dotnet:8
   FROM mcr.microsoft.com/dotnet/runtime:9.0
   
   # Set the image's internal work directory
   WORKDIR /var/task
     
   # Copy function code to Lambda-defined environment variable
   COPY "bin/Release/net9.0/linux-x64"  .
     
   # Set the entrypoint to the bootstrap
   ENTRYPOINT ["/usr/bin/dotnet", "exec", "/var/task/bootstrap.dll"]
   ```

1. Installa lo [strumento globale .NET Core](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/) Amazon.Lambda.Tools.

   ```
   dotnet tool install -g Amazon.Lambda.Tools
   ```

   Se Amazon.Lambda.Tools è già installato, assicurati di disporre della versione più recente.

   ```
   dotnet tool update -g Amazon.Lambda.Tools
   ```

1. Utilizza Amazon.Lambda.Tools per creare l'immagine Docker, trasferirla in un nuovo repository Amazon ECR e implementare la funzione Lambda.

   Per `--function-role`, specifica il nome del ruolo, non il nome della risorsa Amazon (ARN), del [ruolo di esecuzione](lambda-intro-execution-role.md) della funzione. Ad esempio, `lambda-role`.

   ```
   dotnet lambda deploy-function MyFunction --function-role lambda-role
   ```

   [Per ulteriori informazioni sull'estensione CLI di Amazon.Lambda.Tools, consulta l'archivio Extensions for .NET CLI su.AWS](https://github.com/aws/aws-extensions-for-dotnet-cli) GitHub

1. Richiama la funzione.

   ```
   dotnet lambda invoke-function MyFunction --payload "Testing the function"
   ```

   In caso di esito positivo, viene visualizzato quanto segue:

   ```
   Payload:
   "TESTING THE FUNCTION"
   
   Log Tail:
   START RequestId: id Version: $LATEST
   END RequestId: id
   REPORT RequestId: id  Duration: 0.99 ms       Billed Duration: 1 ms         Memory Size: 256 MB     Max Memory Used: 12 MB
   ```

1. Elimina la funzione Lambda.

   ```
   dotnet lambda delete-function MyFunction
   ```

# Compilare il codice della funzione Lambda .NET in un formato di runtime nativo
<a name="dotnet-native-aot"></a>

.NET 8 supporta la compilazione nativa in anticipo (AOT). Con AOT nativa, puoi compilare il codice della funzione Lambda in un formato di runtime nativo, che elimina la necessità di compilare il codice .NET in fase di runtime. La compilazione AOT nativa può ridurre il tempo di avvio a freddo delle funzioni Lambda scritte in .NET. Per ulteriori informazioni, consulta il post [Introduzione del runtime .NET 8 per AWS Lambda](https://aws.amazon.com/blogs/compute/introducing-the-net-8-runtime-for-aws-lambda/) sul blog AWS Compute.

**Topics**
+ [

## Runtime Lambda
](#dotnet-native-aot-runtime)
+ [

## Prerequisiti
](#dotnet-native-aot-prerequisites)
+ [

## Nozioni di base
](#dotnet-native-aot-getting-started)
+ [

## Serializzazione
](#dotnet-native-aot-serialization)
+ [

## Rifinitura
](#dotnet-native-aot-trimming)
+ [

## Risoluzione dei problemi
](#dotnet-native-aot-troubleshooting)

## Runtime Lambda
<a name="dotnet-native-aot-runtime"></a>

Per implementare una funzione Lambda creata con la compilazione AOT nativa, usa il runtime Lambda .NET 8 gestito. Questo runtime supporta l'uso sia di architetture x86\$164 che di architetture arm64.

Quando si implementa una funzione Lambda .NET, l'applicazione viene prima compilata in codice IL (Intermediate Language). Al runtime, il compilatore just-in-time (JIT) nel runtime Lambda prende il codice IL e lo compila in codice macchina secondo le necessità. Con una funzione Lambda compilata in anticipo con AOT nativo, si compila il codice in codice macchina quando si implementa la funzione in modo da non dipendere dal runtime .NET o dall'SDK nel runtime Lambda per compilare il codice prima che venga eseguito.

Una limitazione di AOT è che il codice dell'applicazione deve essere compilato in un ambiente con lo stesso sistema operativo Amazon Linux 2023 (AL2023) utilizzando dal runtime .NET 8. La CLI Lambda .NET offre funzionalità per compilare l'applicazione in un container Docker utilizzando un'immagine AL2023.

Per evitare potenziali problemi di compatibilità tra le architetture, consigliamo vivamente di compilare il codice in un ambiente con la stessa architettura di processore configurata per la funzione. Per ulteriori informazioni sui limiti della compilazione tra architetture diverse, consulta [Compilazione incrociata](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/cross-compile) nella documentazione di Microsoft .NET.

## Prerequisiti
<a name="dotnet-native-aot-prerequisites"></a>

**Docker**  
Per utilizzare l'AOT nativo, il codice della funzione deve essere compilato in un ambiente con lo stesso sistema operativo AL2023 del runtime .NET 8. I comandi della CLI .NET nelle seguenti sezioni utilizzano Docker per sviluppare e creare funzioni Lambda in un ambiente AL2023.

**SDK .NET 8**  
La compilazione AOT nativa è una funzionalità di .NET 8. È necessario installare l'[SDK .NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) sulla macchina di compilazione, non solo il runtime.

**Amazon.Lambda.Tools**  
Per creare le funzioni Lambda, usa l'[estensione degli strumenti globali .NET](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/) [https://www.nuget.org/packages/Amazon.Lambda.Tools](https://www.nuget.org/packages/Amazon.Lambda.Tools). Per installare Amazon.Lambda.Tools, esegui il comando riportato:  

```
dotnet tool install -g Amazon.Lambda.Tools
```
Per ulteriori informazioni sull'estensione della CLI .NET Amazon.Lambda.Tools, consulta il repository [Estensioni AWS per la CLI .NET](https://github.com/aws/aws-extensions-for-dotnet-cli) su GitHub.

**Amazon.Lambda.Templates**  
Per generare il codice della funzione Lambda, usa il pacchetto [https://www.nuget.org/packages/Amazon.Lambda.Templates](https://www.nuget.org/packages/Amazon.Lambda.Templates) NuGet. Per installare questo pacchetto del modello, esegui il comando riportato:  

```
dotnet new install Amazon.Lambda.Templates
```

## Nozioni di base
<a name="dotnet-native-aot-getting-started"></a>

Sia la CLI globale .NET che AWS Serverless Application Model (AWS SAM) forniscono modelli introduttivi per la creazione di applicazioni utilizzando AOT nativo. Per creare la tua prima funzione Lambda AOT nativa, completa le operazioni riportate nelle seguenti istruzioni.

**Inizializzazione e distribuzione di una funzione Lambda compilata in AOT nativa**

1. Inizializza un nuovo progetto utilizzando il modello AOT nativo, quindi naviga nella directory contenente i file `.cs` e `.csproj` creati. In questo esempio, diamo un nome alla nostra funzione `NativeAotSample`.

   ```
   dotnet new lambda.NativeAOT -n NativeAotSample
   cd ./NativeAotSample/src/NativeAotSample
   ```

   Il file `Function.cs` creato dal modello AOT nativo contiene il seguente codice di funzione.

   ```
   using Amazon.Lambda.Core;
   using Amazon.Lambda.RuntimeSupport;
   using Amazon.Lambda.Serialization.SystemTextJson;
   using System.Text.Json.Serialization;
   
   namespace NativeAotSample;
   
   public class Function
   {
       /// <summary>
       /// The main entry point for the Lambda function. The main function is called once during the Lambda init phase. It
       /// initializes the .NET Lambda runtime client passing in the function handler to invoke for each Lambda event and
       /// the JSON serializer to use for converting Lambda JSON format to the .NET types.
       /// </summary>
       private static async Task Main()
       {
           Func<string, ILambdaContext, string> handler = FunctionHandler;
           await LambdaBootstrapBuilder.Create(handler, new SourceGeneratorLambdaJsonSerializer<LambdaFunctionJsonSerializerContext>())
               .Build()
               .RunAsync();
       }
   
       /// <summary>
       /// A simple function that takes a string and does a ToUpper.
       ///
       /// To use this handler to respond to an AWS event, reference the appropriate package from
       /// https://github.com/aws/aws-lambda-dotnet#events
       /// and change the string input parameter to the desired event type. When the event type
       /// is changed, the handler type registered in the main method needs to be updated and the LambdaFunctionJsonSerializerContext
       /// defined below will need the JsonSerializable updated. If the return type and event type are different then the
       /// LambdaFunctionJsonSerializerContext must have two JsonSerializable attributes, one for each type.
       ///
       // When using Native AOT extra testing with the deployed Lambda functions is required to ensure
       // the libraries used in the Lambda function work correctly with Native AOT. If a runtime
       // error occurs about missing types or methods the most likely solution will be to remove references to trim-unsafe
       // code or configure trimming options. This sample defaults to partial TrimMode because currently the AWS
       // SDK for .NET does not support trimming. This will result in a larger executable size, and still does not
       // guarantee runtime trimming errors won't be hit.
       /// </summary>
       /// <param name="input"></param>
       /// <param name="context"></param>
       /// <returns></returns>
       public static string FunctionHandler(string input, ILambdaContext context)
       {
           return input.ToUpper();
       }
   }
   
   /// <summary>
   /// This class is used to register the input event and return type for the FunctionHandler method with the System.Text.Json source generator.
   /// There must be a JsonSerializable attribute for each type used as the input and return type or a runtime error will occur
   /// from the JSON serializer unable to find the serialization information for unknown types.
   /// </summary>
   [JsonSerializable(typeof(string))]
   public partial class LambdaFunctionJsonSerializerContext : JsonSerializerContext
   {
       // By using this partial class derived from JsonSerializerContext, we can generate reflection free JSON Serializer code at compile time
       // which can deserialize our class and properties. However, we must attribute this class to tell it what types to generate serialization code for.
       // See https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-source-generation
   ```

   AOT nativo compila l'applicazione in un unico binario nativo. Il punto di ingresso di quel binario è il metodo `static Main`. All'interno di `static Main`, viene avviato il runtime Lambda e viene impostato il metodo `FunctionHandler`. Come parte del bootstrap di runtime, un serializzatore generato dal codice sorgente viene configurato utilizzando `new SourceGeneratorLambdaJsonSerializer<LambdaFunctionJsonSerializerContext>()`

1. Per distribuire l'applicazione in Lambda, assicurati che Docker sia in esecuzione nel tuo ambiente locale ed esegui il comando riportato.

   ```
   dotnet lambda deploy-function
   ```

   Dietro le quinte, la CLI globale .NET scarica un'immagine Docker di AL2023 e compila il codice dell'applicazione all'interno di un container in esecuzione. Il file binario compilato viene restituito al file system locale prima di essere implementato su Lambda.

1. Verifica la tua funzione eseguendo il comando riportato. Sostituisci `<FUNCTION_NAME>` con il nome scelto per la funzione nella procedura guidata di implementazione.

   ```
   dotnet lambda invoke-function <FUNCTION_NAME> --payload "hello world"
   ```

   La risposta della CLI include dettagli sulle prestazioni per l'avvio a freddo (durata di inizializzazione) e il runtime totale per l'invocazione della funzione.

1. Per eliminare le risorse AWS create seguendo i passaggi precedenti, esegui il comando riportato. Sostituisci `<FUNCTION_NAME>` con il nome scelto per la funzione nella procedura guidata di implementazione. Eliminando le risorse AWS che non si utilizzano più, è possibile evitare addebiti superflui sul proprio Account AWS.

   ```
   dotnet lambda delete-function <FUNCTION_NAME>
   ```

## Serializzazione
<a name="dotnet-native-aot-serialization"></a>

Per implementare le funzioni in Lambda utilizzando AOT nativo, il codice della funzione deve utilizzare la [serializzazione generata dal codice sorgente](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/source-generation-modes?pivots=dotnet-8-0). Invece di utilizzare la riflessione in fase di esecuzione per raccogliere i metadati necessari per accedere alle proprietà degli oggetti per la serializzazione, i generatori di codice sorgente generano file sorgente C\$1 che vengono compilati durante la creazione dell'applicazione. Per configurare correttamente il serializzatore generato dal codice sorgente, assicurati di includere tutti gli oggetti di input e output utilizzati dalla funzione, nonché tutti i tipi personalizzati. Ad esempio, una funzione Lambda che riceve eventi da una REST API di Gateway API e restituisce un tipo `Product` personalizzato includerebbe un serializzatore definito come segue.

```
[JsonSerializable(typeof(APIGatewayProxyRequest))]
[JsonSerializable(typeof(APIGatewayProxyResponse))]
[JsonSerializable(typeof(Product))]
public partial class CustomSerializer : JsonSerializerContext
{
}
```

## Rifinitura
<a name="dotnet-native-aot-trimming"></a>

L'AOT nativo rifinisce il codice dell'applicazione come parte della compilazione per garantire che il file binario sia il più piccolo possibile. .NET 8 for Lambda offre un supporto di rifinitura migliorato rispetto alle versioni precedenti di .NET. È stato aggiunto il supporto alle [librerie di runtime Lambda](https://github.com/aws/aws-lambda-dotnet/pull/1596), all'[SDK AWS .NET](https://github.com/aws/aws-sdk-net/pulls?q=is%3Apr+trimming) alle [annotazioni Lambda .NET](https://github.com/aws/aws-lambda-dotnet/pull/1610) e a .NET 8 stesso.

Questi miglioramenti offrono la possibilità di eliminare gli avvisi di rifinitura in fase di compilazione, ma .NET non sarà mai completamente esente da tale problema. Ciò significa che parti delle librerie su cui si basa la funzione possono essere eliminate durante la fase di compilazione. Puoi gestire questo problema definendo `TrimmerRootAssemblies` come parte del tuo file `.csproj`, come mostrato nell'esempio seguente. 

```
<ItemGroup>
    <TrimmerRootAssembly Include="AWSSDK.Core" />
    <TrimmerRootAssembly Include="AWSXRayRecorder.Core" />
    <TrimmerRootAssembly Include="AWSXRayRecorder.Handlers.AwsSdk" />
    <TrimmerRootAssembly Include="Amazon.Lambda.APIGatewayEvents" />
    <TrimmerRootAssembly Include="bootstrap" />
    <TrimmerRootAssembly Include="Shared" />
</ItemGroup>
```

Tieni presente che quando ricevi un avviso di rifinitura, l'aggiunta della classe che genera l'avviso `TrimmerRootAssembly` potrebbe non risolvere il problema. Un avviso di rifinitura indica che la classe sta provando ad accedere a un'altra classe che non può essere determinata fino al runtime. Per evitare errori di runtime, aggiungi questa seconda classe a `TrimmerRootAssembly`.

Per ulteriori informazioni sulla gestione degli avvisi di rifinitura, consulta [Introduzione agli avvisi di rifinitura](https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/fixing-warnings) nella documentazione di Microsoft .NET.

## Risoluzione dei problemi
<a name="dotnet-native-aot-troubleshooting"></a>

**Errore: la compilazione nativa tra sistemi operativi non è supportata.**  
La tua versione dello strumento globale .NET Core di Amazon.Lambda.Tools non è aggiornata. Esegui l'aggiornamento alla versione più recente e riprova.

**Docker: il sistema operativo di immagini "linux" non può essere utilizzato su questa piattaforma.**  
Docker sul tuo sistema è configurato per utilizzare container Windows. Passa ai container Linux per eseguire l'ambiente della compilazione AOT nativa.

Per ulteriori informazioni sugli errori più comuni, consulta il repository [AWSNativeAOT per .NET](https://github.com/awslabs/dotnet-nativeaot-labs#common-errors) su GitHub.

# Utilizzo dell'oggetto del contesto Lambda per recuperare le informazioni sulla funzione C\$1
<a name="csharp-context"></a>

Quando Lambda esegue la funzione, passa un oggetto Context al [gestore](csharp-handler.md). Questo oggetto fornisce proprietà con informazioni sulla chiamata, sulla funzione e sull'ambiente di esecuzione.

**Proprietà del contesto**
+ `FunctionName`: il nome della funzione Lambda.
+ `FunctionVersion`: la [versione](configuration-versions.md) della funzione.
+ `InvokedFunctionArn`: l'Amazon Resource Name (ARN) utilizzato per richiamare la funzione. Indica se l'invoker ha specificato un numero di versione o un alias.
+ `MemoryLimitInMB`: la quantità di memoria allocata per la funzione.
+ `AwsRequestId`: l'identificatore della richiesta di invocazione.
+ `LogGroupName`: il gruppo di log per la funzione.
+ `LogStreamName`: il flusso di log per l'istanza della funzione.
+ `RemainingTime` (`TimeSpan`): il numero di millisecondi rimasti prima del timeout dell'esecuzione.
+ `Identity`: (app per dispositivi mobili) Informazioni relative all'identità Amazon Cognito che ha autorizzato la richiesta.
+ `ClientContext`: (app per dispositivi mobili) Contesto client fornito a Lambda dall'applicazione client.
+ `Logger` L'[oggetto logger](csharp-logging.md) per la funzione.

Puoi utilizzare le informazioni riportate nell'oggetto `ILambdaContext` per generare informazioni sull'invocazione della funzione a scopo di monitoraggio. Il seguente codice fornisce un esempio di come aggiungere informazioni di contesto a un framework di registrazione strutturato. In questo esempio, la funzione aggiunge `AwsRequestId` agli output di log. La funzione utilizza anche la proprietà `RemainingTime` per annullare un'attività in transito se il timeout della funzione Lambda sta per essere raggiunto.

```
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace GetProductHandler;

public class Function
{
    private readonly IDatabaseRepository _repo;
    
    public Function()
    {
        this._repo = new DatabaseRepository();
    }
    
    public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest request, ILambdaContext context)
    {
        Logger.AppendKey("AwsRequestId", context.AwsRequestId);
        
        var id = request.PathParameters["id"];

        using var cts = new CancellationTokenSource();
        
        try
        {
            cts.CancelAfter(context.RemainingTime.Add(TimeSpan.FromSeconds(-1)));
            
            var databaseRecord = await this._repo.GetById(id, cts.Token);
            
            return new APIGatewayProxyResponse 
            {
                StatusCode = (int)HttpStatusCode.OK,
                Body = JsonSerializer.Serialize(databaseRecord)
            };
        }
        catch (Exception ex)
        {
            return new APIGatewayProxyResponse 
            {
                StatusCode = (int)HttpStatusCode.InternalServerError,
                Body = JsonSerializer.Serialize(new { error = ex.Message })
            };
        }
        finally
        {
            cts.Cancel();
        }
    }
}
```

# Registrare e monitorare le funzioni Lambda con C\$1
<a name="csharp-logging"></a>

AWS Lambda monitora automaticamente le funzioni Lambda e invia le voci di registro ad Amazon. CloudWatch La funzione Lambda include un gruppo di log CloudWatch Logs e un flusso di log per ogni istanza della funzione. L'ambiente di runtime di Lambda invia al flusso di log i dettagli su ogni invocazione e altri output dal codice della funzione. Per ulteriori informazioni sui CloudWatch registri, consulta. [Lambda invia automaticamente i log delle funzioni a CloudWatch Logs.](monitoring-cloudwatchlogs.md)

**Topics**
+ [

## Creazione di una funzione che restituisce i registri
](#csharp-logging-output)
+ [

## Utilizzo dei controlli di registrazione avanzati di Lambda con .NET
](#csharp-logging-advanced)
+ [

## Strumenti e librerie di registrazione aggiuntivi
](#csharp-tools-libraries)
+ [

## Utilizzo di Powertools per AWS Lambda (.NET) e per la registrazione strutturata AWS SAM
](#dotnet-logging-sam)
+ [

## Visualizzazione dei log nella console Lambda
](#csharp-logging-console)
+ [

## Visualizzazione dei log nella console CloudWatch
](#csharp-logging-cwconsole)
+ [

## Visualizzazione dei log utilizzando () AWS Command Line Interface AWS CLI
](#csharp-logging-cli)
+ [

## Eliminazione dei log
](#csharp-logging-delete)

## Creazione di una funzione che restituisce i registri
<a name="csharp-logging-output"></a>

Per generare i log dal codice della funzione, potete utilizzare il [ILambdaLogger](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.Core/ILambdaLogger.cs) sull'oggetto context, i metodi sulla [classe Console](https://docs.microsoft.com/en-us/dotnet/api/system.console) o qualsiasi libreria di registrazione che scrive su o. `stdout` `stderr`

Il runtime di .NET registra `START`, `END` e `REPORT` per ogni chiamata. La riga del report fornisce i seguenti dettagli.

**Campi dati della riga REPORT**
+ **RequestId**— L'ID univoco della richiesta per la chiamata.
+ **Durata** – La quantità di tempo che il metodo del gestore della funzione impiega durante l'elaborazione dell'evento.
+ **Durata fatturata** – La quantità di tempo fatturata per la chiamata.
+ **Dimensioni memoria** – La quantità di memoria allocata per la funzione.
+ **Quantità max utilizzata** – La quantità di memoria utilizzata dalla funzione. Quando le invocazioni condividono un ambiente di esecuzione, Lambda riporta la memoria massima utilizzata in tutte le invocazioni. Questo comportamento potrebbe comportare un valore riportato superiore al previsto.
+ **Durata Init** – Per la prima richiesta servita, la quantità di tempo impiegato dal runtime per caricare la funzione ed eseguire il codice al di fuori del metodo del gestore.
+ **XRAY TraceId** [— Per le richieste tracciate, l'ID di traccia.AWS X-Ray](services-xray.md)
+ **SegmentId**— Per le richieste tracciate, l'ID del segmento X-Ray.
+ **Campionato** – Per le richieste tracciate, il risultato del campionamento.

## Utilizzo dei controlli di registrazione avanzati di Lambda con .NET
<a name="csharp-logging-advanced"></a>

Per avere un maggiore controllo sul modo in cui i log delle tue funzioni vengono acquisiti, elaborati e utilizzati, puoi configurare le seguenti opzioni di registrazione per i runtime .NET supportati:
+ **Formato di log**: scegli tra i formati di testo normale e JSON strutturato per i log della funzione
+ **Livello di registro**: per i log in formato JSON, scegli il livello di dettaglio dei log a cui Lambda invia, CloudWatch ad esempio ERROR, DEBUG o INFO
+ Gruppo di **log: scegli il gruppo** di log a cui la CloudWatch funzione invia i log

Per ulteriori informazioni su queste opzioni di registrazione e istruzioni su come configurare la funzione per utilizzarle, consulta la pagina [Configurazione dei controlli di registrazione avanzati per le funzioni Lambda](monitoring-logs.md#monitoring-cloudwatchlogs-advanced).

Per utilizzare le opzioni del formato di log e del livello di log con le funzioni Lambda in .NET, consulta le istruzioni nelle sezioni seguenti.

### Utilizzo del formato di log JSON strutturato con .NET
<a name="csharp-logging-advanced-JSON"></a>

Se si seleziona JSON per il formato di registro della funzione, Lambda invierà l'output dei log [ILambdautilizzando](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.Core/ILambdaLogger.cs) Logger come JSON strutturato. Ogni oggetto di log JSON contiene almeno cinque coppie chiave-valore con le seguenti chiavi:
+ `"timestamp"`: l'ora in cui è stato generato il messaggio di log
+ `"level"`: il livello di log assegnato al messaggio
+ `"requestId"`: l'ID di richiesta univoco dell'invocazione alla funzione
+ `"traceId"`: la variabile di ambiente `_X_AMZN_TRACE_ID`
+ `"message"`: il contenuto del messaggio di log

L'istanza `ILambdaLogger` può aggiungere ulteriori coppie chiave-valore, ad esempio durante la registrazione delle eccezioni. È inoltre possibile fornire parametri aggiuntivi personalizzati come descritto nella sezione [Parametri di log forniti dal cliente](#csharp-logging-advanced-JSON-user-supplied).

**Nota**  
Se il codice utilizza già un'altra libreria di registrazione per generare log in formato JSON, assicurati che il formato di log della funzione sia impostato su testo semplice. L'impostazione del formato di log su JSON comporterà la doppia codifica degli output dei log.

Il seguente comando di registrazione di esempio mostra come scrivere un messaggio di log con il livello `INFO`.

**Example codice di registrazione .NET**  

```
context.Logger.LogInformation("Fetching cart from database");
```

Inoltre, puoi usare un metodo di log generico che utilizza il livello di log come argomento come mostrato nell'esempio seguente.

```
context.Logger.Log(LogLevel.Information, "Fetching cart from database");
```

L'output di registro di questi frammenti di codice di esempio verrebbe acquisito in Logs come segue: CloudWatch 

**Example Record di log JSON**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Information",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "Fetching cart from database"
}
```

**Nota**  
Se configuri il formato di log della funzione per utilizzare testo semplice anziché JSON, il livello di log acquisito nel messaggio segue la convenzione di Microsoft di utilizzare un'etichetta di quattro caratteri. Ad esempio, un livello di log di `Debug` è rappresentato nel messaggio come `dbug`.  
Quando si configura la funzione per l'utilizzo di log in formato JSON, il livello di log acquisito nel log utilizza l'etichetta completa, come mostrato nel record di log JSON di esempio.

Se non assegni un livello all'output log, Lambda gli assegnerà automaticamente il livello INFO.

#### Registrazione delle eccezioni in JSON
<a name="csharp-logging-advanced-JSON-exceptions"></a>

Quando si utilizza la registrazione JSON strutturata con `ILambdaLogger`, è possibile registrare le eccezioni dei log nel codice come illustrato nell'esempio seguente.

**Example utilizzo della registrazione delle eccezioni**  

```
try
{
    connection.ExecuteQuery(query);
}
catch(Exception e)
{
    context.Logger.LogWarning(e, "Error executing query");
}
```

Il formato di log generato da questo codice è mostrato nell'esempio JSON seguente. Si noti che la proprietà `message` in JSON viene compilata utilizzando l'argomento del messaggio fornito nella chiamata `LogWarning`, mentre la proprietà `errorMessage` proviene dalla proprietà `Message` dell'eccezione stessa.

**Example Record di log JSON**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Warning",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "Error executing query",
    "errorType": "System.Data.SqlClient.SqlException",
    "errorMessage": "Connection closed",
    "stackTrace": ["<call exception.StackTrace>"]
}
```

Se il formato di registrazione della funzione è impostato su JSON, Lambda emette anche messaggi di log in formato JSON quando il codice genera un'eccezione non rilevata. Il frammento di codice e il messaggio di log di esempio seguenti mostrano come vengono registrate le eccezioni non rilevate.

**Example codice di eccezione**  

```
throw new ApplicationException("Invalid data");
```

**Example Record di log JSON**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Error",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "Invalid data",
    "errorType": "System.ApplicationException",
    "errorMessage": "Invalid data",
    "stackTrace": ["<call exception.StackTrace>"]
}
```

#### Parametri di log forniti dal cliente
<a name="csharp-logging-advanced-JSON-user-supplied"></a>

Con i messaggi di log in formato JSON, è possibile fornire parametri di log aggiuntivi e includerli nel log `message`. Il seguente esempio di frammento di codice mostra un comando per aggiungere due parametri forniti dall'utente etichettati `retryAttempt` e `uri`. Nell'esempio, il valore di questi parametri deriva dagli argomenti `retryAttempt` e `uriDestination` passati al comando di registrazione.

**Example Comando di registrazione JSON con parametri aggiuntivi**  

```
context.Logger.LogInformation("Starting retry {retryAttempt} to make GET request to {uri}", retryAttempt, uriDestination);
```

L'output del messaggio di log di questo comando è mostrato nell'esempio JSON seguente.

**Example Record di log JSON**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Information",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "Starting retry 1 to make GET request to http://example.com/",
    "retryAttempt": 1,
    "uri": "http://example.com/"
}
```

**Suggerimento**  
Quando si specificano parametri aggiuntivi, è inoltre possibile utilizzare proprietà posizionali anziché nomi. A titolo illustrativo, il comando di registrazione nell'esempio precedente potrebbe essere scritto anche come segue:  

```
context.Logger.LogInformation("Starting retry {0} to make GET request to {1}", retryAttempt, uriDestination);
```

Tieni presente che quando fornisci parametri di registrazione aggiuntivi, Lambda li acquisisce come proprietà di primo livello nel record di log JSON. Questo approccio è diverso da alcune popolari librerie di registrazione .NET come `Serilog`, che acquisiscono parametri aggiuntivi in un oggetto secondario separato.

Se l'argomento fornito per un parametro aggiuntivo è un oggetto complesso, per impostazione predefinita Lambda utilizza il metodo `ToString()` per fornire il valore. Per indicare che un argomento deve essere serializzato in JSON, utilizza il prefisso `@` come mostrato nel seguente frammento di codice. In questo esempio, `User` è un oggetto con proprietà `FirstName` e `LastName`.

**Example Comando di registrazione JSON con oggetto serializzato JSON**  

```
context.Logger.LogInformation("User {@user} logged in", User);
```

L'output del messaggio di log di questo comando è mostrato nell'esempio JSON seguente.

**Example Record di log JSON**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Information",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "User {@user} logged in",
    "user": 
    {
        "FirstName": "John",
        "LastName": "Doe"
    }
}
```

Se l'argomento per un parametro aggiuntivo è un array o implementa `IList` o`IDictionary`, Lambda aggiunge l'argomento al messaggio di log JSON come matrice, come mostrato nell'esempio seguente di record di log JSON. In questo esempio, `{users}` accetta un argomento `IList` contenente istanze della proprietà `User` con lo stesso formato dell'esempio precedente. Lambda converte `IList` in un array, con ogni valore creato utilizzando il metodo `ToString`.

**Example Record di log JSON con un argomento `IList`**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Information",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "{users} have joined the group",
    "users": 
    [
        "Rosalez, Alejandro",
        "Stiles, John"       
    ] 
}
```

Puoi serializzare l'elenco in JSON anche utilizzando il prefisso `@` nel comando di registrazione. Nel seguente esempio di record di log JSON, la proprietà `users` è serializzata in JSON.

**Example Record di log JSON con un argomento `IList` serializzato in JSON**  

```
{
    "timestamp": "2025-09-07T01:30:06.977Z",
    "level": "Information",
    "requestId": "8f711428-7e55-46f9-ae88-2a65d4f85fc5",
    "traceId": "1-6408af34-50f56f5b5677a7d763973804",
    "message": "{@users} have joined the group",
    "users": 
    [
        {
            "FirstName": "Alejandro",
            "LastName": "Rosalez"
        },
        {
            "FirstName": "John",
            "LastName": "Stiles"
        }        
    ] 
}
```

### Utilizzo del filtraggio a livello di log con .NET
<a name="csharp-logging-advanced-levels"></a>

Configurando il filtraggio a livello di registro, è possibile scegliere di inviare a Logs solo i log con un determinato livello di dettaglio o inferiore. CloudWatch Per informazioni su come configurare il filtraggio a livello di log della funzione, consulta la pagina [Filtraggio a livello di log](monitoring-cloudwatchlogs-log-level.md).

Per AWS Lambda filtrare i messaggi di registro in base al livello di registro, è possibile utilizzare registri in formato JSON o utilizzare i metodi.NET per generare messaggi di registro. `Console` Per creare log in formato JSON, [configura il tipo di log della funzione su JSON](monitoring-cloudwatchlogs-logformat.md#monitoring-cloudwatchlogs-set-format) e usa l'istanza `ILambdaLogger`.

Con i log in formato JSON, Lambda filtra gli output dei log utilizzando la coppia chiave-valore "livello" nell'oggetto JSON descritto in [Utilizzo del formato di log JSON strutturato con .NET](#csharp-logging-advanced-JSON).

Se utilizzi i `Console` metodi.NET per scrivere messaggi CloudWatch nei registri, Lambda applica i livelli di registro ai tuoi messaggi come segue:
+ **Console. WriteLine **metodo - Lambda applica un livello di registro di `INFO`
+ **Metodo Console.Error**: Lambda applica il livello di log `ERROR`

Quando configuri la funzione per utilizzare il filtraggio a livello di log, devi selezionare una delle seguenti opzioni per il livello di log che Lambda invii a Logs. CloudWatch Nota la mappatura dei livelli di log utilizzati da Lambda con i livelli Microsoft standard utilizzati da .NET `ILambdaLogger`.


| Livello di log Lambda | Livello Microsoft equivalente | Utilizzo standard | 
| --- | --- | --- | 
| TRACE (dettaglio massimo) | Traccia | Le informazioni più dettagliate utilizzate per tracciare il percorso di esecuzione del codice | 
| DEBUG | Esegui il debug | Informazioni dettagliate per il debug del sistema | 
| INFO | Informazioni | Messaggi che registrano il normale funzionamento della funzione | 
| WARN | Attenzione | Messaggi relativi a potenziali errori che possono portare a comportamenti imprevisti se non risolti | 
| ERRORE | Errore | Messaggi relativi a problemi che impediscono al codice di funzionare come previsto | 
| FATAL (dettaglio minimo) | Critica | Messaggi relativi a errori gravi che causano l'interruzione del funzionamento dell'applicazione | 

Lambda invia i log del livello di dettaglio selezionato e inferiore a. CloudWatch Ad esempio, se configuri un livello di log WARN, Lambda invierà i log corrispondenti ai livelli WARN, ERROR e FATAL.

## Strumenti e librerie di registrazione aggiuntivi
<a name="csharp-tools-libraries"></a>

[Powertools for AWS Lambda (.NET)](https://docs.aws.amazon.com/powertools/dotnet/) è un toolkit per sviluppatori che implementa le migliori pratiche Serverless e aumenta la velocità degli sviluppatori. L'[utilità di registrazione](https://docs.aws.amazon.com/powertools/dotnet/core/logging/) fornisce un logger ottimizzato per Lambda che include informazioni aggiuntive sul contesto delle funzioni in tutte le funzioni con output strutturato come JSON. Utilizza l'utility per eseguire le seguenti operazioni:
+ Acquisizione di campi essenziali dal contesto Lambda, avvii a freddo e output di registrazione della struttura come JSON
+ Registrazione degli eventi di chiamata Lambda quando richiesto (disabilitata per impostazione predefinita)
+ Stampa di tutti i log solo per una percentuale di chiamate tramite campionamento dei log (disabilitata per impostazione predefinita)
+ Aggiunta di chiavi supplementari al log strutturato in qualsiasi momento
+ Utilizzo di un formattatore di log personalizzato (Bring Your Own Formatter) per generare i log in una struttura compatibile con Logging RFC dell'organizzazione

## Utilizzo di Powertools per AWS Lambda (.NET) e per la registrazione strutturata AWS SAM
<a name="dotnet-logging-sam"></a>

Segui i passaggi seguenti per scaricare, creare e distribuire un'applicazione Hello World C\$1 di esempio con moduli [Powertools for AWS Lambda (.NET)](https://docs.powertools.aws.dev/lambda-dotnet) integrati utilizzando il. AWS SAM Questa applicazione implementa un backend dell'API di base e utilizza Powertools per l'emissione di log, parametri e tracce. Consiste in un endpoint Gateway Amazon API e in una funzione Lambda. Quando invii una richiesta GET all'endpoint API Gateway, la funzione Lambda richiama, invia log e metriche utilizzando Embedded Metric Format e invia tracce a. CloudWatch AWS X-Ray La funzione restituisce un messaggio `hello world`.

**Prerequisiti**

Per completare le fasi riportate in questa sezione, è necessario:
+ .NET 8
+ [AWS CLI versione 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS SAM CLI versione 1.75](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) o successiva. Se disponi di una versione precedente della AWS SAM CLI, consulta [Aggiornamento](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade) della CLI. AWS SAM 

**Implementa un'applicazione di esempio AWS SAM**

1. Inizializza l'applicazione utilizzando il modello Hello World. TypeScript 

   ```
   sam init --app-template hello-world-powertools-dotnet --name sam-app --package-type Zip --runtime dotnet6 --no-tracing
   ```

1. Costruisci l'app.

   ```
   cd sam-app && sam build
   ```

1. Distribuire l'app.

   ```
   sam deploy --guided
   ```

1. Seguire le istruzioni visualizzate sullo schermo. Per accettare le opzioni predefinite fornite nell'esperienza interattiva, premi `Enter`.
**Nota**  
Perché **HelloWorldFunction potrebbe non avere un'autorizzazione definita. Va bene?** , assicurati di entrare`y`.

1. Ottieni l'URL dell'applicazione implementata:

   ```
   aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
   ```

1. Richiama l'endpoint dell'API:

   ```
   curl -X GET <URL_FROM_PREVIOUS_STEP>
   ```

   In caso di esito positivo, vedrai questa risposta:

   ```
   {"message":"hello world"}
   ```

1. Per ottenere i log per la funzione, esegui [sam logs](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-logs.html). Per ulteriori informazioni, consulta l'argomento relativo all'[utilizzo dei log](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-logging.html) nella *Guida per sviluppatori AWS Serverless Application Model *.

   ```
   sam logs --stack-name sam-app
   ```

   L'output del log ha la struttura seguente:

   ```
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:27.988000 INIT_START Runtime Version: dotnet:6.v13        Runtime Version ARN: arn:aws:lambda:ap-southeast-2::runtime:699f346a05dae24c58c45790bc4089f252bf17dae3997e79b17d939a288aa1ec
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:28.229000 START RequestId: bed25b38-d012-42e7-ba28-f272535fb80e Version: $LATEST
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:29.259000 2025-09-20T14:15:29.201Z        bed25b38-d012-42e7-ba28-f272535fb80e    info   {"_aws":{"Timestamp":1676902528962,"CloudWatchMetrics":[{"Namespace":"sam-app-logging","Metrics":[{"Name":"ColdStart","Unit":"Count"}],"Dimensions":[["FunctionName"],["Service"]]}]},"FunctionName":"sam-app-HelloWorldFunction-haKIoVeose2p","Service":"PowertoolsHelloWorld","ColdStart":1}
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:30.479000 2025-09-20T14:15:30.479Z        bed25b38-d012-42e7-ba28-f272535fb80e    info   {"ColdStart":true,"XrayTraceId":"1-63f3807f-5dbcb9910c96f50742707542","CorrelationId":"d3d4de7f-4ccc-411a-a549-4d67b2fdc015","FunctionName":"sam-app-HelloWorldFunction-haKIoVeose2p","FunctionVersion":"$LATEST","FunctionMemorySize":256,"FunctionArn":"arn:aws:lambda:ap-southeast-2:123456789012:function:sam-app-HelloWorldFunction-haKIoVeose2p","FunctionRequestId":"bed25b38-d012-42e7-ba28-f272535fb80e","Timestamp":"2025-09-20T14:15:30.4602970Z","Level":"Information","Service":"PowertoolsHelloWorld","Name":"AWS.Lambda.Powertools.Logging.Logger","Message":"Hello world API - HTTP 200"}
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:30.599000 2025-09-20T14:15:30.599Z        bed25b38-d012-42e7-ba28-f272535fb80e    info   {"_aws":{"Timestamp":1676902528922,"CloudWatchMetrics":[{"Namespace":"sam-app-logging","Metrics":[{"Name":"ApiRequestCount","Unit":"Count"}],"Dimensions":[["Service"]]}]},"Service":"PowertoolsHelloWorld","ApiRequestCount":1}
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:30.680000 END RequestId: bed25b38-d012-42e7-ba28-f272535fb80e
   2025/02/20/[$LATEST]4eaf8445ba7a4a93b999cb17fbfbecd8 2025-09-20T14:15:30.680000 REPORT RequestId: bed25b38-d012-42e7-ba28-f272535fb80e  Duration: 2450.99 ms   Billed Duration: 2692 ms Memory Size: 256 MB     Max Memory Used: 74 MB  Init Duration: 240.05 ms
   XRAY TraceId: 1-63f3807f-5dbcb9910c96f50742707542       SegmentId: 16b362cd5f52cba0
   ```

1. Questo è un endpoint API pubblico accessibile su Internet. È consigliabile eliminare l'endpoint dopo il test.

   ```
   sam delete
   ```

### Gestione della conservazione dei log
<a name="csharp-log-retention"></a>

I gruppi di log non vengono eliminati automaticamente quando si elimina una funzione. Per evitare di archiviare i log a tempo indeterminato, elimina il gruppo di log o configura un periodo di conservazione dopo il quale i log CloudWatch vengono eliminati automaticamente. Per configurare la conservazione dei log, aggiungi quanto segue al tuo modello: AWS SAM 

```
Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      # Omitting other properties

  LogGroup:
    Type: AWS::Logs::LogGroup
    Properties:
      LogGroupName: !Sub "/aws/lambda/${HelloWorldFunction}"
      RetentionInDays: 7
```

## Visualizzazione dei log nella console Lambda
<a name="csharp-logging-console"></a>

È possibile utilizzare la console Lambda per visualizzare l'output del log dopo aver richiamato una funzione Lambda.

Se il codice può essere testato dall'editor del **codice** incorporato, troverai i log nei **risultati dell’esecuzione**. Quando utilizzi la funzionalità di test della console per richiamare una funzione, troverai l’**output del log** nella sezione **Dettagli**.

## Visualizzazione dei log nella console CloudWatch
<a name="csharp-logging-cwconsole"></a>

Puoi utilizzare la CloudWatch console Amazon per visualizzare i log di tutte le chiamate di funzioni Lambda.

**Per visualizzare i log sulla console CloudWatch**

1. Apri la [pagina Registra gruppi](https://console.aws.amazon.com/cloudwatch/home?#logs:) sulla CloudWatch console.

1. Scegli il gruppo di log per la tua funzione (***your-function-name*/aws/lambda/**).

1. Creare un flusso di log.

Ogni flusso di log corrisponde a un'[istanza della funzione](lambda-runtime-environment.md). Viene visualizzato un flusso di log quando aggiorni la funzione Lambda e quando vengono create istanze aggiuntive per gestire le chiamate simultanee. Per trovare i log per una chiamata specifica, consigliamo di strumentare la funzione con. AWS X-Ray X-Ray registra i dettagli sulla richiesta e il flusso di log nella traccia.

## Visualizzazione dei log utilizzando () AWS Command Line Interface AWS CLI
<a name="csharp-logging-cli"></a>

 AWS CLI È uno strumento open source che consente di interagire con i AWS servizi utilizzando i comandi nella shell della riga di comando. Per completare le fasi riportate in questa sezione, è necessario disporre della [AWS CLI versione 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).

È possibile utilizzare [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) per recuperare i log per una chiamata utilizzando l'opzione di comando `--log-type`. La risposta include un campo `LogResult` che contiene fino a 4 KB di log con codifica base64 del richiamo.

**Example recuperare un ID di log**  
Nell'esempio seguente viene illustrato come recuperare un *ID di log* dal `LogResult` campo per una funzione denominata `my-function`.  

```
aws lambda invoke --function-name my-function out --log-type Tail
```
Verrà visualizzato l’output seguente:  

```
{
    "StatusCode": 200,
    "LogResult": "U1RBUlQgUmVxdWVzdElkOiA4N2QwNDRiOC1mMTU0LTExZTgtOGNkYS0yOTc0YzVlNGZiMjEgVmVyc2lvb...",
    "ExecutedVersion": "$LATEST"
}
```

**Example decodificare i log**  
Nello stesso prompt dei comandi, utilizzare l'`base64` utilità per decodificare i log. Nell'esempio seguente viene illustrato come recuperare i log codificati in base64 per `my-function`.  

```
aws lambda invoke --function-name my-function out --log-type Tail \
--query 'LogResult' --output text --cli-binary-format raw-in-base64-out | base64 --decode
```
L'**cli-binary-format**opzione è obbligatoria se si utilizza la AWS CLI versione 2. Per rendere questa impostazione come predefinita, esegui `aws configure set cli-binary-format raw-in-base64-out`. Per ulteriori informazioni, consulta la pagina [AWS CLI supported global command line options](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) nella *Guida per l'utente di AWS Command Line Interface versione 2*.  
Verrà visualizzato l’output seguente:  

```
START RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8 Version: $LATEST
"AWS_SESSION_TOKEN": "AgoJb3JpZ2luX2VjELj...", "_X_AMZN_TRACE_ID": "Root=1-5d02e5ca-f5792818b6fe8368e5b51d50;Parent=191db58857df8395;Sampled=0"",ask/lib:/opt/lib",
END RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8
REPORT RequestId: 57f231fb-1730-4395-85cb-4f71bd2b87b8  Duration: 79.67 ms      Billed Duration: 80 ms         Memory Size: 128 MB     Max Memory Used: 73 MB
```
L'utilità `base64` è disponibile su Linux, macOS e [Ubuntu su Windows](https://docs.microsoft.com/en-us/windows/wsl/install-win10). Gli utenti macOS potrebbero dover utilizzare `base64 -D`.

**Example Script get-logs.sh**  
Nello stesso prompt dei comandi, utilizzare lo script seguente per scaricare gli ultimi cinque eventi di log. Lo script utilizza `sed` per rimuovere le virgolette dal file di output e rimane in sospensione per 15 secondi in attesa che i log diventino disponibili. L'output include la risposta di Lambda e l'output del comando `get-log-events`.   
Copiare il contenuto del seguente esempio di codice e salvare nella directory del progetto Lambda come `get-logs.sh`.  
L'**cli-binary-format**opzione è obbligatoria se utilizzi la AWS CLI versione 2. Per rendere questa impostazione come predefinita, esegui `aws configure set cli-binary-format raw-in-base64-out`. Per ulteriori informazioni, consulta la pagina [AWS CLI supported global command line options](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) nella *Guida per l'utente di AWS Command Line Interface versione 2*.  

```
#!/bin/bash
aws lambda invoke --function-name my-function --cli-binary-format raw-in-base64-out --payload '{"key": "value"}' out
sed -i'' -e 's/"//g' out
sleep 15
aws logs get-log-events --log-group-name /aws/lambda/my-function --log-stream-name stream1 --limit 5
```

**Example (solo) macOS e Linux**  
Nello stesso prompt dei comandi, gli utenti macOS e Linux potrebbero dover eseguire il seguente comando per assicurarsi che lo script sia eseguibile.  

```
chmod -R 755 get-logs.sh
```

**Example recuperare gli ultimi cinque eventi di log**  
Nello stesso prompt dei comandi, eseguire lo script seguente per ottenere gli ultimi cinque eventi di log.  

```
./get-logs.sh
```
Verrà visualizzato l’output seguente:  

```
{
    "StatusCode": 200,
    "ExecutedVersion": "$LATEST"
}
{
    "events": [
        {
            "timestamp": 1559763003171,
            "message": "START RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf Version: $LATEST\n",
            "ingestionTime": 1559763003309
        },
        {
            "timestamp": 1559763003173,
            "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tENVIRONMENT VARIABLES\r{\r  \"AWS_LAMBDA_FUNCTION_VERSION\": \"$LATEST\",\r ...",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003173,
            "message": "2019-06-05T19:30:03.173Z\t4ce9340a-b765-490f-ad8a-02ab3415e2bf\tINFO\tEVENT\r{\r  \"key\": \"value\"\r}\n",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003218,
            "message": "END RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\n",
            "ingestionTime": 1559763018353
        },
        {
            "timestamp": 1559763003218,
            "message": "REPORT RequestId: 4ce9340a-b765-490f-ad8a-02ab3415e2bf\tDuration: 26.73 ms\tBilled Duration: 27 ms \tMemory Size: 128 MB\tMax Memory Used: 75 MB\t\n",
            "ingestionTime": 1559763018353
        }
    ],
    "nextForwardToken": "f/34783877304859518393868359594929986069206639495374241795",
    "nextBackwardToken": "b/34783877303811383369537420289090800615709599058929582080"
}
```

## Eliminazione dei log
<a name="csharp-logging-delete"></a>

I gruppi di log non vengono eliminati automaticamente quando si elimina una funzione. Per evitare di archiviare i log a tempo indeterminato, eliminare il gruppo di log o [configurare un periodo di conservazione](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#SettingLogRetention) trascorso il quale i log vengono eliminati automaticamente.

# Strumentazione del codice C\$1 in AWS Lambda
<a name="csharp-tracing"></a>

Lambda si integra con AWS X-Ray per aiutarti a tracciare, eseguire il debug e ottimizzare le applicazioni Lambda. Puoi utilizzare X-Ray per tracciare una richiesta mentre attraversa le risorse nell'applicazione, che possono includere funzioni Lambda e altri servizi AWS .

Per inviare dati di tracciamento a X-Ray, è possibile utilizzare una delle tre librerie SDK:
+ [AWS Distro for OpenTelemetry (ADOT)](https://aws.amazon.com/otel): una distribuzione sicura, pronta per la produzione e supportata dell'SDK (). AWS OpenTelemetry OTel
+ [SDK AWS X-Ray per .NET](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-dotnet.html): un SDK per generare e inviare i dati di traccia su X-Ray.
+ [Powertools for AWS Lambda (.NET)](https://docs.aws.amazon.com/powertools/dotnet/): un toolkit per sviluppatori per implementare le migliori pratiche Serverless e aumentare la velocità degli sviluppatori.

Ciascuno di essi SDKs offre modi per inviare i dati di telemetria al servizio X-Ray. Puoi quindi utilizzare X-Ray per visualizzare, filtrare e analizzare le metriche delle prestazioni dell'applicazione per identificare i problemi e le opportunità di ottimizzazione.

**Importante**  
X-Ray e Powertools per AWS Lambda SDKs fanno parte di una soluzione di strumentazione strettamente integrata offerta da. AWS I livelli Lambda ADOT fanno parte di uno standard di settore per la strumentazione di tracciamento che in generale raccoglie più dati, ma potrebbero non essere adatti a tutti i casi d'uso. È possibile implementare il end-to-end tracciamento in X-Ray utilizzando entrambe le soluzioni. Per saperne di più sulla scelta tra di esse, consulta [Scelta tra AWS Distro for Open Telemetry](https://docs.aws.amazon.com/xray/latest/devguide/xray-instrumenting-your-app.html#xray-instrumenting-choosing) e X-Ray. SDKs

**Topics**
+ [

## Utilizzo di Powertools per (.NET) e per il AWS Lambda tracciamento AWS SAM
](#dotnet-tracing-sam)
+ [

## Utilizzo dell'SDK X-Ray per strumentare le funzioni .NET
](#dotnet-xray-sdk)
+ [

## Attivazione del tracciamento con la console Lambda
](#dotnet-tracing-console)
+ [

## Attivazione del tracciamento con l'API Lambda
](#dotnet-tracing-api)
+ [

## Attivazione del tracciamento con CloudFormation
](#dotnet-tracing-cloudformation)
+ [

## Interpretazione di una traccia X-Ray
](#dotnet-tracing-interpretation)

## Utilizzo di Powertools per (.NET) e per il AWS Lambda tracciamento AWS SAM
<a name="dotnet-tracing-sam"></a>

Segui i passaggi seguenti per scaricare, creare e distribuire un'applicazione Hello World C\$1 di esempio con i moduli [Powertools for AWS Lambda (.NET)](https://docs.powertools.aws.dev/lambda-dotnet) integrati utilizzando. AWS SAM Questa applicazione implementa un backend dell'API di base e utilizza Powertools per l'emissione di log, parametri e tracce. Consiste in un endpoint Gateway Amazon API e in una funzione Lambda. Quando invii una richiesta GET all'endpoint API Gateway, la funzione Lambda richiama, invia log e metriche utilizzando Embedded Metric Format e invia tracce a. CloudWatch AWS X-Ray La funzione restituisce un messaggio hello world.

**Prerequisiti**

Per completare le fasi riportate in questa sezione, è necessario:
+ .NET 8
+ [AWS CLI versione 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS SAM CLI versione 1.75](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) o successiva. Se disponi di una versione precedente della AWS SAM CLI, consulta [Aggiornamento](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade) della CLI. AWS SAM 

**Implementa un'applicazione di esempio AWS SAM**

1. Inizializza l'applicazione utilizzando il modello Hello World. TypeScript 

   ```
   sam init --app-template hello-world-powertools-dotnet --name sam-app --package-type Zip --runtime dotnet6 --no-tracing
   ```

1. Costruisci l'app.

   ```
   cd sam-app && sam build
   ```

1. Distribuire l'app.

   ```
   sam deploy --guided
   ```

1. Seguire le istruzioni visualizzate sullo schermo. Per accettare le opzioni predefinite fornite nell'esperienza interattiva, premi `Enter`.
**Nota**  
Perché **HelloWorldFunction potrebbe non avere un'autorizzazione definita. Va bene?** , assicurati di entrare`y`.

1. Ottieni l'URL dell'applicazione implementata:

   ```
   aws cloudformation describe-stacks --stack-name sam-app --query 'Stacks[0].Outputs[?OutputKey==`HelloWorldApi`].OutputValue' --output text
   ```

1. Richiama l'endpoint dell'API:

   ```
   curl <URL_FROM_PREVIOUS_STEP>
   ```

   In caso di esito positivo, vedrai questa risposta:

   ```
   {"message":"hello world"}
   ```

1. Per ottenere le tracce per la funzione, esegui [sam traces](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-traces.html).

   ```
   sam traces
   ```

   L'output della traccia ha il seguente aspetto:

   ```
   New XRay Service Graph
     Start time: 2023-02-20 23:05:16+08:00
     End time: 2023-02-20 23:05:16+08:00
     Reference Id: 0 - AWS::Lambda - sam-app-HelloWorldFunction-pNjujb7mEoew - Edges: [1]
      Summary_statistics:
        - total requests: 1
        - ok count(2XX): 1
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 2.814
     Reference Id: 1 - AWS::Lambda::Function - sam-app-HelloWorldFunction-pNjujb7mEoew - Edges: []
      Summary_statistics:
        - total requests: 1
        - ok count(2XX): 1
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 2.429
     Reference Id: 2 - (Root) AWS::ApiGateway::Stage - sam-app/Prod - Edges: [0]
      Summary_statistics:
        - total requests: 1
        - ok count(2XX): 1
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 2.839
     Reference Id: 3 - client - sam-app/Prod - Edges: [2]
      Summary_statistics:
        - total requests: 0
        - ok count(2XX): 0
        - error count(4XX): 0
        - fault count(5XX): 0
        - total response time: 0
   
   XRay Event [revision 3] at (2023-02-20T23:05:16.521000) with id (1-63f38c2c-270200bf1d292a442c8e8a00) and duration (2.877s)
    - 2.839s - sam-app/Prod [HTTP: 200]
      - 2.836s - Lambda [HTTP: 200]
    - 2.814s - sam-app-HelloWorldFunction-pNjujb7mEoew [HTTP: 200]
    - 2.429s - sam-app-HelloWorldFunction-pNjujb7mEoew
      - 0.230s - Initialization
      - 2.389s - Invocation
        - 0.600s - ## FunctionHandler
          - 0.517s - Get Calling IP
      - 0.039s - Overhead
   ```

1. Questo è un endpoint API pubblico accessibile su Internet. È consigliabile eliminare l'endpoint dopo il test.

   ```
   sam delete
   ```

X-Ray non traccia tutte le richieste nell'applicazione. X-Ray applica un algoritmo di campionamento per garantire che il tracciamento avvenga in modo efficiente, continuando allo stesso tempo a fornire un campione rappresentativo di tutte le richieste. La frequenza di campionamento è di una richiesta al secondo e del 5% delle altre richieste. Non è possibile configurare la frequenza di campionamento di X-Ray per le funzioni.

## Utilizzo dell'SDK X-Ray per strumentare le funzioni .NET
<a name="dotnet-xray-sdk"></a>

È possibile utilizzare il codice funzione per registrare i metadati e tracciare le chiamate a valle. Per registrare i dettagli delle chiamate effettuate dalla funzione ad altre risorse e servizi, utilizza SDK AWS X-Ray per .NET. Per ottenere l'SDK, aggiungere i pacchetti `AWSXRayRecorder` al file di progetto.

```
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
    <AWSProjectType>Lambda</AWSProjectType>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Amazon.Lambda.Core" Version="2.1.0" />
    <PackageReference Include="Amazon.Lambda.SQSEvents" Version="2.1.0" />
    <PackageReference Include="Amazon.Lambda.Serialization.Json" Version="2.1.0" />
    <PackageReference Include="AWSSDK.Core" Version="3.7.103.24" />
    <PackageReference Include="AWSSDK.Lambda" Version="3.7.104.3" />
    <PackageReference Include="AWSXRayRecorder.Core" Version="2.13.0" />
    <PackageReference Include="AWSXRayRecorder.Handlers.AwsSdk" Version="2.11.0" />
  </ItemGroup>
</Project>
```

Esistono diversi pacchetti Nuget che forniscono strumentazione automatica per richieste Entity Framework e AWS SDKs HTTP. Per visualizzare il set completo di opzioni di configurazione, consulta [SDK AWS X-Ray per .NET](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-dotnet.html) nella *Guida per gli sviluppatori di AWS X-Ray *.

Dopo aver aggiunto i pacchetti Nuget desiderati, configura la strumentazione automatica. Una best practice consiste nell'eseguire questa configurazione al di fuori della funzione di gestione della funzione. Ciò consente di sfruttare il riutilizzo dell'ambiente di esecuzione per migliorare le prestazioni della funzione. Nel seguente esempio di codice, il `RegisterXRayForAllServices` metodo viene chiamato nel costruttore di funzioni per aggiungere la strumentazione per tutte le chiamate SDK. AWS 

```
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace GetProductHandler;

public class Function
{
    private readonly IDatabaseRepository _repo;
    
    public Function()
    {
        // Add auto instrumentation for all AWS SDK calls
        // It is important to call this method before initializing any SDK clients
        AWSSDKHandler.RegisterXRayForAllServices();
        this._repo = new DatabaseRepository();
    }
    
    public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest request)
    {
        var id = request.PathParameters["id"];
        
        var databaseRecord = await this._repo.GetById(id);
        
        return new APIGatewayProxyResponse 
        {
            StatusCode = (int)HttpStatusCode.OK,
            Body = JsonSerializer.Serialize(databaseRecord)
        };
    }
}
```

## Attivazione del tracciamento con la console Lambda
<a name="dotnet-tracing-console"></a>

Per attivare il tracciamento attivo sulla funzione Lambda con la console, attenersi alla seguente procedura:

**Per attivare il tracciamento attivo**

1. Aprire la pagina [Funzioni](https://console.aws.amazon.com/lambda/home#/functions) della console Lambda.

1. Scegliere una funzione.

1. Scegliere **Configuration** (Configurazione) e quindi **Monitoring and operations tools** (Strumenti di monitoraggio e operazioni).

1. In **Strumenti di monitoraggio aggiuntivi** scegli **Modifica**.

1. In **CloudWatch Application Signals e AWS X-Ray**, scegli **Enable** for **Lambda service trace**.

1. Scegli **Save** (Salva).

## Attivazione del tracciamento con l'API Lambda
<a name="dotnet-tracing-api"></a>

Configura il tracciamento sulla tua funzione Lambda con AWS o SDK, utilizza AWS CLI le seguenti operazioni API:
+ [UpdateFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionConfiguration.html)
+ [GetFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionConfiguration.html)
+ [CreateFunction](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html)

**Il AWS CLI comando di esempio seguente abilita il tracciamento attivo su una funzione denominata my-function.**

```
aws lambda update-function-configuration --function-name my-function \
--tracing-config Mode=Active
```

La modalità di tracciamento fa parte della configurazione specifica della versione quando si pubblica una versione della funzione. Non è possibile modificare la modalità di tracciamento in una versione pubblicata.

## Attivazione del tracciamento con CloudFormation
<a name="dotnet-tracing-cloudformation"></a>

Per attivare il tracciamento su una `AWS::Lambda::Function` risorsa in un CloudFormation modello, utilizzate la proprietà. `TracingConfig`

**Example [function-inline.yml](https://github.com/awsdocs/aws-lambda-developer-guide/blob/master/templates/function-inline.yml) – Configurazione del tracciamento**  

```
Resources:
  function:
    Type: [AWS::Lambda::Function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)
    Properties:
      TracingConfig:
        Mode: Active
      ...
```

Per una `AWS::Serverless::Function` risorsa AWS Serverless Application Model (AWS SAM), utilizzate la `Tracing` proprietà.

**Example [template.yml](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-nodejs/template.yml) – Configurazione del tracciamento**  

```
Resources:
  function:
    Type: [AWS::Serverless::Function](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html)
    Properties:
      Tracing: Active
      ...
```

## Interpretazione di una traccia X-Ray
<a name="dotnet-tracing-interpretation"></a>

La funzione ha bisogno dell'autorizzazione per caricare i dati di traccia su X-Ray. Quando si attiva il tracciamento nella console Lambda, Lambda aggiunge le autorizzazioni necessarie al [ruolo di esecuzione](lambda-intro-execution-role.md) della funzione. Altrimenti, aggiungete la [AWSXRayDaemonWriteAccess](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess)politica al ruolo di esecuzione.

Dopo aver configurato il tracciamento attivo, è possibile osservare richieste specifiche tramite l'applicazione. Il [grafico dei servizi X-Ray](https://docs.aws.amazon.com/xray/latest/devguide/aws-xray.html#xray-concepts-servicegraph) mostra informazioni sull'applicazione e tutti i suoi componenti. Il seguente esempio mostra un'applicazione con due funzioni. La funzione principale elabora gli eventi e talvolta restituisce errori. La seconda funzione in alto elabora gli errori che compaiono nel gruppo di log della prima e utilizza l' AWS SDK per chiamare X-Ray, Amazon Simple Storage Service (Amazon S3) e Amazon Logs. CloudWatch 

![\[\]](http://docs.aws.amazon.com/it_it/lambda/latest/dg/images/sample-errorprocessor-servicemap.png)


X-Ray non traccia tutte le richieste nell'applicazione. X-Ray applica un algoritmo di campionamento per garantire che il tracciamento avvenga in modo efficiente, continuando allo stesso tempo a fornire un campione rappresentativo di tutte le richieste. La frequenza di campionamento è di una richiesta al secondo e del 5% delle altre richieste. Non è possibile configurare la frequenza di campionamento di X-Ray per le funzioni.

In X-Ray, una *traccia* registra informazioni su una richiesta elaborata da uno o più *servizi*. Lambda registra 2 segmenti per traccia, che creano due nodi sul grafico del servizio. L'immagine seguente evidenzia questi due nodi:

![\[\]](http://docs.aws.amazon.com/it_it/lambda/latest/dg/images/xray-servicemap-function.png)


Il primo nodo a sinistra rappresenta il servizio Lambda che riceve la richiesta di chiamata. Il secondo nodo rappresenta la specifica funzione Lambda. L'esempio seguente mostra una traccia con questi 2 segmenti. Entrambi sono nominati **my-function**, ma uno ha l'origine `AWS::Lambda` e l'altro ha l'origine `AWS::Lambda::Function`. Se il segmento `AWS::Lambda` mostra un errore, il servizio Lambda ha avuto un problema. Se il `AWS::Lambda::Function` segmento mostra un errore, la funzione ha avuto un problema.

![\[\]](http://docs.aws.amazon.com/it_it/lambda/latest/dg/images/V2_sandbox_images/my-function-2-v1.png)


Questo esempio espande il segmento `AWS::Lambda::Function` per visualizzare i relativi tre sottosegmenti.

**Nota**  
AWS sta attualmente implementando modifiche al servizio Lambda. A causa di queste modifiche, potresti notare piccole differenze tra la struttura e il contenuto dei messaggi di log di sistema e dei segmenti di traccia emessi da diverse funzioni Lambda nel tuo Account AWS.  
La traccia di esempio mostrata qui illustra il segmento di funzione vecchio stile. Le differenze tra i segmenti vecchio e nuovo stile sono descritte nei paragrafi seguenti.  
Queste modifiche verranno implementate nelle prossime settimane e tutte le funzioni, Regioni AWS ad eccezione della Cina e delle GovCloud regioni, passeranno all'utilizzo dei messaggi di registro e dei segmenti di traccia di nuovo formato.

Il segmento di funzioni vecchio stile contiene i seguenti sottosegmenti:
+ **Inizializzazione** – Rappresenta il tempo trascorso a caricare la funzione e ad eseguire il [codice di inizializzazione](foundation-progmodel.md). Questo sottosegmento viene visualizzato solo per il primo evento che viene elaborato da ogni istanza della funzione.
+ **Chiamata**: rappresenta il tempo impiegato per eseguire il codice del gestore.
+ **Overhead**: rappresenta il tempo impiegato dal runtime Lambda per prepararsi a gestire l'evento successivo.

Il segmento di funzione di nuovo stile non contiene un sottosegmento `Invocation`. I sottosegmenti dei clienti sono invece collegati direttamente al segmento di funzioni. Per ulteriori informazioni sulla struttura dei segmenti di funzioni vecchio e nuovo stile, consulta [Informazioni sui monitoraggi di X-Ray](services-xray.md#services-xray-traces).

È inoltre possibile strumentare i client HTTP, registrare query SQL e creare segmenti secondari personalizzati con annotazioni e metadati. Per ulteriori informazioni, consulta [SDK AWS X-Ray per .NET](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-dotnet.html) nella *Guida per gli sviluppatori di AWS X-Ray *.

**Prezzi**  
Puoi utilizzare il tracciamento X-Ray gratuitamente ogni mese fino a un determinato limite come parte del AWS piano gratuito. Oltre la soglia, X-Ray addebita lo storage di traccia e il recupero. Per ulteriori informazioni, consultare [Prezzi di AWS X-Ray](https://aws.amazon.com/xray/pricing/).

# Test della funzione AWS Lambda in C\$1
<a name="dotnet-csharp-testing"></a>

**Nota**  
Consulta il capitolo sul [Test delle funzioni](testing-guide.md) per un'introduzione completa alle tecniche e alle best practice per testare soluzioni serverless. 

 Sebbene il test delle funzioni serverless si basi su tipologie e tecniche di test consolidate, è importante tenere in considerazione la possibilità di effettuare test sulle applicazioni serverless nella loro interezza. I test basati sul cloud forniranno la misura **più accurata** della qualità sia delle funzioni sia delle applicazioni serverless. 

 Un'architettura applicativa serverless include servizi gestiti che forniscono funzionalità applicative critiche tramite chiamate API. Pertanto, è fondamentale che il ciclo di sviluppo preveda test automatici in grado di verificare il corretto funzionamento dell'interazione tra le funzioni e i servizi. 

 Se non crei test basati sul cloud, potresti riscontrare problemi dovuti alle differenze tra l'ambiente locale e quello implementato. Il processo di integrazione continua dovrebbe eseguire test su un insieme di risorse con provisioning nel cloud prima di promuovere il codice nell'ambiente di implementazione successivo, come quello di controllo qualità (QA), staging o produzione. 

 Continua a leggere questa breve guida per scoprire le strategie di test per le applicazioni serverless oppure visita il [repository Serverless Test Samples](https://github.com/aws-samples/serverless-test-samples) per approfondire esempi pratici, specifici per il linguaggio e il runtime selezionati. 

 ![\[illustration showing the relationship between types of tests\]](http://docs.aws.amazon.com/it_it/lambda/latest/dg/images/test-type-illustration2.png) 

 Per i test in ambito serverless, è necessario scrivere *test unitari*, *test di integrazione* e *test end-to-end*. 
+ **Test unitari**: vengono eseguiti su un blocco di codice isolato. Ad esempio, possono essere utilizzati per verificare la logica aziendale per calcolare le spese di spedizione in base a un articolo e a una destinazione specifici.
+ **Test di integrazione**: coinvolgono due o più componenti o servizi che interagiscono, in genere in un ambiente cloud. Ad esempio, possono essere utilizzati per verificare che una funzione elabori gli eventi di una coda.
+ **Test end-to-end**: verificano il comportamento di un'intera applicazione. Ad esempio, possono essere utilizzati per verificare che l'infrastruttura sia configurata correttamente e che gli eventi fluiscano tra i servizi come previsto per registrare l'ordine di un cliente.

## Test delle applicazioni serverless
<a name="dotnet-csharp-testing-techniques-for-serverless-applications"></a>

 Generalmente, utilizzerai una combinazione di approcci per testare il codice dell'applicazione serverless, inclusi test nel cloud, test con mock e occasionalmente test con emulatori. 

### Test nel cloud
<a name="dotnet-csharp-testing-in-the-cloud"></a>

 I test nel cloud sono utili per tutte le fasi di test, inclusi i test unitari, i test di integrazione e i test end-to-end. Esegui test su codice implementato nel cloud e interagisci con servizi basati su cloud. Questo approccio fornisce la misura **più accurata** della qualità del codice. 

 Un modo conveniente per eseguire il debug di una funzione Lambda nel cloud è con un evento di test nella console. Un *evento di test* è un input JSON per la funzione. Se la funzione non richiede input, l'evento può essere un documento JSON `({})` vuoto. La console fornisce eventi di esempio per una varietà di integrazioni di servizi. Dopo aver creato un evento nella console, puoi condividerlo con il tuo team per rendere i test più semplici e coerenti. 

**Nota**  
[Testare una funzione nella console](testing-functions.md) è un modo rapido per iniziare, ma l'automazione dei cicli di test garantisce la qualità delle applicazioni e la velocità di sviluppo. 

### Strumenti di test
<a name="dotnet-csharp-testing-tools"></a>

Per accelerare il ciclo di sviluppo, esistono diversi strumenti e tecniche che è possibile utilizzare durante il test delle funzioni. Ad esempio, [AWS SAM Accelerate](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/using-sam-cli-sync.html) e [AWS CDK CDK watch mode](https://docs.aws.amazon.com/cdk/v2/guide/cli.html#cli-deploy-watch) riducono entrambi il tempo necessario per aggiornare gli ambienti cloud.

Il modo in cui definisci il codice della funzione Lambda semplifica l'aggiunta di test unitari. Per inizializzare la classe, Lambda richiede un costruttore pubblico senza parametri. L'introduzione di un secondo costruttore interno consente di controllare le dipendenze utilizzate dall'applicazione.

```
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]

namespace GetProductHandler;

public class Function
{
    private readonly IDatabaseRepository _repo;
    
    public Function(): this(null)
    {
    }
    
    internal Function(IDatabaseRepository repo)
    {
        this._repo = repo ?? new DatabaseRepository();
    }
    
    public async Task<APIGatewayProxyResponse> FunctionHandler(APIGatewayProxyRequest request)
    {
        var id = request.PathParameters["id"];
        
        var databaseRecord = await this._repo.GetById(id);
        
        return new APIGatewayProxyResponse 
        {
            StatusCode = (int)HttpStatusCode.OK,
            Body = JsonSerializer.Serialize(databaseRecord)
        };
    }
}
```

Per scrivere un test per questa funzione, puoi inizializzare una nuova istanza della classe `Function` e passare un'implementazione simulata di `IDatabaseRepository`. Gli esempi seguenti utilizzano `XUnit`, `Moq` e `FluentAssertions` per scrivere un semplice test che assicuri che `FunctionHandler` restituisca un codice di stato 200. 

```
using Xunit;
using Moq;
using FluentAssertions;

public class FunctionTests
{
    [Fact]
    public async Task TestLambdaHandler_WhenInputIsValid_ShouldReturn200StatusCode()
    {
        // Arrange
        var mockDatabaseRepository = new Mock<IDatabaseRepository>();
        
        var functionUnderTest = new Function(mockDatabaseRepository.Object);
        
        // Act
        var response = await functionUnderTest.FunctionHandler(new APIGatewayProxyRequest());
        
        // Assert
        response.StatusCode.Should().Be(200);
    }
}
```

Per esempi più dettagliati, inclusi esempi di test asincroni, consulta il [repository di esempi di test .NET](https://github.com/aws-samples/serverless-test-samples/tree/main/dotnet-test-samples) su GitHub.