

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Erstellen von Lambda-Funktionen mit C\$1
<a name="lambda-csharp"></a>

Sie können Ihre .NET-Anwendung in Lambda mit der verwalteten .NET 8-Laufzeit, einer benutzerdefinierten Laufzeit oder einem Container-Image ausführen. Nachdem Ihr Anwendungscode kompiliert wurde, können Sie ihn entweder als ZIP-Datei oder als Container-Image für Lambda bereitstellen. Lambda stellt die folgenden Laufzeiten für .NET-Sprachen bereit:


| Name | ID | Betriebssystem | Datum der Veraltung | Blockfunktion erstellen | Blockfunktion aktualisieren | 
| --- | --- | --- | --- | --- | --- | 
|  .NET 10  |  `dotnet10`  |  Amazon Linux 2023  |   14. November 2028   |   14. Dezember 2028   |   15. Januar 2029   | 
|  .NET 9 (nur Container)  |  `dotnet9`  |  Amazon Linux 2023  |   10. November 2026   |   Nicht geplant   |   Nicht geplant   | 
|  .NET 8  |  `dotnet8`  |  Amazon Linux 2023  |   10. November 2026   |   10. Dezember 2026   |   11. Januar 2027   | 

## Einrichten der .NET-Entwicklungsumgebung
<a name="csharp-dev-env"></a>

Um Ihre Lambda-Funktionen zu entwickeln und zu erstellen, können Sie jede der allgemein verfügbaren.NET-integrierten Entwicklungsumgebungen (IDEs) verwenden, einschließlich Microsoft Visual Studio, Visual Studio Code und JetBrains Rider. Zur Vereinfachung Ihrer Entwicklungserfahrung AWS bietet es eine Reihe von .NET-Projektvorlagen sowie die `Amazon.Lambda.Tools` Befehlszeilenschnittstelle (CLI).

Führen Sie die folgenden .NET-CLI-Befehle aus, um diese Projektvorlagen und Befehlszeilentools zu installieren.

### Installieren der .NET-Projektvorlagen
<a name="csharp-dev-env-templates"></a>

Zur Installation der Projektvorlagen führen Sie den folgenden Befehl aus:

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

### Installation und Aktualisierung der CLI-Tools
<a name="csharp-dev-env-cli-tools"></a>

Führen Sie die folgenden Befehle aus, um die `Amazon.Lambda.Tools`-CLI zu installieren, zu aktualisieren und zu deinstallieren.

Installieren der Befehlszeilen-Tools:

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

Aktualisieren der Befehlszeilen-Tools:

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

Deinstallieren der Befehlszeilen-Tools:

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

# Definieren des Lambda-Funktions-Handlers in C\$1
<a name="csharp-handler"></a>

Der Lambda-Funktions*handler* ist die Methode in Ihrem Funktionscode, die Ereignisse verarbeitet. Wenn Ihre Funktion aufgerufen wird, führt Lambda die Handler-Methode aus. Ihre Funktion wird so lange ausgeführt, bis der Handler eine Antwort zurückgibt, beendet wird oder ein Timeout auftritt.

Auf dieser Seite wird beschrieben, wie Sie Lambda-Funktionshandler in C\$1 verwenden, um mit der verwalteten .NET-Laufzeit zu arbeiten, einschließlich der Optionen für Projekteinrichtung, Benennungskonventionen und Best Practices. Diese Seite enthält auch ein Beispiel für eine C\$1-Lambda-Funktion, die Informationen über eine Bestellung aufnimmt, eine Textdatei als Beleg erstellt und diese Datei in einen Bucket in Amazon Simple Storage Service (S3) stellt. Informationen darüber, wie Sie Ihre Funktion nach dem Schreiben einsetzen können, finden Sie unter [Erstellen und Bereitstellen von C\$1-Lambda-Funktionen mit ZIP-Dateiarchiven](csharp-package.md) oder [Bereitstellen von .NET-Lambda-Funktionen mit Container-Images](csharp-image.md).

**Topics**
+ [

## Einrichten Ihres C\$1-Handler-Projekts
](#csharp-handler-setup)
+ [

## Beispiel für den C\$1-Lambda-Funktionscode
](#csharp-example-code)
+ [

## Handler für Klassenbibliotheken
](#csharp-class-library-handlers)
+ [

## Ausführbare Assembly-Handler
](#csharp-executable-assembly-handlers)
+ [

## Gültige Handler-Signaturen für C\$1-Funktionen
](#csharp-handler-signatures)
+ [

## Namenskonventionen für Handler
](#csharp-handler-naming)
+ [

## Serialisierung in C\$1-Lambda-Funktionen
](#csharp-handler-serializer)
+ [

## Dateibasierte Funktionen
](#csharp-file-based-functions)
+ [

## Zugreifen auf und Verwenden des Lambda-Kontextobjekts
](#csharp-example-context)
+ [

## Verwenden Sie die SDK für .NET Version 3 in Ihrem Handler
](#csharp-example-sdk-usage)
+ [

## Zugriff auf Umgebungsvariablen
](#csharp-example-envvars)
+ [

## Verwenden des globalen Zustands
](#csharp-handler-state)
+ [

## Vereinfachen Sie den Funktionscode mit dem Lambda Annotations Framework
](#csharp-handler-annotations)
+ [

## Bewährte Codemethoden für C\$1-Lambda-Funktionen
](#csharp-best-practices)

## Einrichten Ihres C\$1-Handler-Projekts
<a name="csharp-handler-setup"></a>

Wenn Sie mit Lambda-Funktionen in C\$1 arbeiten, umfasst der Prozess das Schreiben Ihres Codes und das anschließende Bereitstellen Ihres Codes in Lambda. Es gibt zwei verschiedene Ausführungsmodelle für die Bereitstellung von Lambda-Funktionen in .NET: den Klassenbibliotheksansatz und den Ansatz für ausführbare Assemblys.

Beim Klassenbibliotheksansatz packen Sie Ihren Funktionscode als .NET-Assembly (`.dll`) und stellen ihn mit der verwalteten .NET-Laufzeit (`dotnet8`) in Lambda bereit. Für den Namen des Handlers erwartet Lambda eine Zeichenfolge im Format `AssemblyName::Namespace.Classname::Methodname`. Während der Initialisierungsphase der Funktion wird die Klasse Ihrer Funktion initialisiert und der gesamte Code im Konstruktor wird ausgeführt.

Beim Ansatz für ausführbare Assemblys verwenden Sie das [Feature für Anweisungen der obersten Ebene](https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/top-level-statements), die erstmals in C\$1 9 eingeführt wurde. Dieser Ansatz generiert eine ausführbare Assembly, die Lambda immer dann ausführt, wenn sie einen Aufrufbefehl für Ihre Funktion empfängt. Bei diesem Ansatz verwenden Sie außerdem die verwaltete .NET-Laufzeit (`dotnet8`). Für den Namen des Handlers geben Sie in Lambda den Namen der ausführbaren Assembly an, die ausgeführt werden soll.

Das Hauptbeispiel auf dieser Seite veranschaulicht den Klassenbibliotheksansatz. Sie können Ihr C\$1-Lambda-Projekt auf verschiedene Arten initialisieren. Am einfachsten ist es jedoch, die .NET-CLI mit der `Amazon.Lambda.Tools`-CLI zu verwenden. Richten Sie die `Amazon.Lambda.Tools`-CLI ein, indem Sie die Schritte unter [Einrichten der .NET-Entwicklungsumgebung](lambda-csharp.md#csharp-dev-env) befolgen. Initialisieren Sie das Projekt dann mit dem folgenden Befehl:

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

Dieser Befehl generiert die folgende Dateistruktur:

```
/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 dieser Dateistruktur befindet sich die Hauptlogik des Handlers für Ihre Funktion in der Datei `Function.cs`.

## Beispiel für den C\$1-Lambda-Funktionscode
<a name="csharp-example-code"></a>

Das folgende Beispiel für einen C\$1-Lambda-Funktionscode nimmt Informationen über eine Bestellung auf, erstellt eine Textdatei als Beleg und platziert diese Datei in einem Amazon-S3-Bucket.

**Example `Function.cs`-Lambda-Funktion**  

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

Diese `Function.cs`-Datei enthält die folgenden Abschnitte des Codes:
+ `using`-Anweisungen: Damit können Sie C\$1-Klassen importieren, die für Ihre Lambda-Funktion erforderlich sind.
+ `[assembly: LambdaSerializer(...)]`: `LambdaSerializer` ist ein Assembly-Attribut, das Lambda anweist, JSON-Ereignisnutzdaten automatisch in C\$1-Objekte zu konvertieren, bevor sie an Ihre Funktion übergeben werden.
+ `namespace ExampleLambda`: Dies definiert den Namespace. In C\$1 muss der Namespace-Name nicht mit dem Dateinamen übereinstimmen.
+ `public class Order {...}`: Hiermit wird die Form des erwarteten Eingabeereignisses definiert.
+ `public class OrderHandler {...}`: Hiermit wird die C\$1-Klasse definiert. Darin definieren Sie die Haupt-Handler-Methode und alle anderen Hilfsmethoden.
+ `private static readonly AmazonS3Client s3Client = new();`: Dadurch wird ein Amazon-S3-Client mit der standardmäßigen Anbieterkette von Anmeldeinformationen außerhalb der Haupt-Handler-Methode initialisiert. Dies veranlasst Lambda, diesen Code während der [Initialisierungsphase](lambda-runtime-environment.md#runtimes-lifecycle-ib) auszuführen.
+ `public async ... HandleRequest (Order order, ILambdaContext context)`: Dies ist die **Haupthandler-Methode**, die Ihre Hauptanwendungslogik enthält.
+ `private async Task UploadReceiptToS3(...) {}`: Dies ist eine Hilfsmethode, auf die von der `handleRequest`-Haupthandler-Methode verwiesen wird.

Da für diese Funktion ein SDK-Client für Amazon S3 erforderlich ist, müssen Sie sie zu den Abhängigkeiten Ihres Projekts hinzufügen. Dazu können Sie zu `src/ExampleCS` navigieren und den folgenden Befehl ausführen:

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

### Fügen Sie Metadateninformationen zu aws-lambda-tools-defaults .json hinzu
<a name="csharp-metadata-example"></a>

Standardmäßig enthält die generierte Datei `aws-lambda-tools-defaults.json` keine `profile`- oder `region`-Informationen für Ihre Funktion. Aktualisieren Sie außerdem die `function-handler`-Zeichenfolge auf den richtigen Wert (`ExampleCS::ExampleLambda.OrderHandler::HandleRequest`). Sie können diese Aktualisierung manuell vornehmen und die erforderlichen Metadaten hinzufügen, um ein bestimmtes Anmeldeinformationsprofil und eine bestimmte Region für Ihre Funktion zu verwenden. Die `aws-lambda-tools-defaults.json`-Datei sollte etwa wie folgt aussehen:

```
{
  "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"
}
```

Damit diese Funktion ordnungsgemäß funktioniert, muss ihre [Ausführungsrolle](lambda-intro-execution-role.md) die `s3:PutObject`-Aktion zulassen. Stellen Sie außerdem sicher, dass Sie die `RECEIPT_BUCKET`-Umgebungsvariable definieren. Nach einem erfolgreichen Aufruf sollte der Amazon-S3-Bucket eine Empfangsdatei enthalten.

## Handler für Klassenbibliotheken
<a name="csharp-class-library-handlers"></a>

Der [Hauptbeispielcode](#csharp-example-code) auf dieser Seite veranschaulicht den Klassenbibliotheks-Handler. Klassenbibliotheks-Handler haben die folgende Struktur:

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

namespace NAMESPACE;

...

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

Wenn Sie eine Lambda-Funktion erstellen, müssen Sie Lambda Informationen über den Handler Ihrer Funktion in Form einer Zeichenfolge im Feld [Handler](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-Handler) zur Verfügung stellen. Dadurch wird Lambda mitgeteilt, welche Methode in Ihrem Code ausgeführt werden soll, wenn Ihre Funktion aufgerufen wird. In C\$1 lautet das Format der Handler-Zeichenfolge für Klassenbibliotheks-Handler `ASSEMBLY::TYPE::METHOD`. Dabei gilt Folgendes:
+ `ASSEMBLY` ist der Name der .NET-Assembly-Datei für Ihre Anwendung. Wenn Sie die `Amazon.Lambda.Tools`-CLI zur Erstellung Ihrer Anwendung verwenden und den Assembly-Namen nicht über die Eigenschaft `AssemblyName` in der `.csproj`-Datei festlegen, ist `ASSEMBLY` einfach der Name Ihrer `.csproj`-Datei.
+ `TYPE` ist der vollständige Name des Handler-Typs, der `NAMESPACE.CLASSNAME` lautet.
+ `METHOD` ist der Name der Haupt-Handler-Methode in Ihrem Code. Er lautet `METHODNAME`.

Wenn die Assembly im Hauptbeispielcode auf dieser Seite den Namen `ExampleCS` trägt, lautet die vollständige Zeichenfolge für den Handler `ExampleCS::ExampleLambda.OrderHandler::HandleRequest`.

## Ausführbare Assembly-Handler
<a name="csharp-executable-assembly-handlers"></a>

Sie können Lambda-Funktionen in C\$1 auch als ausführbare Assembly definieren. Handler für ausführbare Assemblys nutzen das C\$1-Feature für Anweisungen der obersten Ebene, bei der der Compiler die `Main()`-Methode generiert und Ihren Funktionscode darin platziert. Bei der Verwendung ausführbarer Assemblys muss die Lambda-Laufzeit gebootet werden. Verwenden Sie dazu die `LambdaBootstrapBuilder.Create`-Methode in Ihrem Code. Die Eingaben für diese Methode stellen die Haupt-Handler-Funktion sowie den Lambda-Serialisierer dar, die verwendet werden sollen. Im Anschluss sehen Sie ein Beispiel für einen Handler für ausführbare Assemblys 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)
    };
};
```

Im Feld [Handler](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-Handler) für Handler für ausführbare Assemblys ist die Handler-Zeichenfolge, die Lambda mitteilt, wie Ihr Code ausgeführt werden soll, der Name der Assembly. In diesem Beispiel ist dies `GetProductHandler`.

## Gültige Handler-Signaturen für C\$1-Funktionen
<a name="csharp-handler-signatures"></a>

In C\$1 können gültige Lambda-Handler-Signaturen zwischen 0 und 2 Argumente enthalten. Normalerweise hat Ihre Handler-Signatur zwei Argumente, wie im Hauptbeispiel gezeigt:

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

Wenn Sie zwei Argumente angeben, muss das erste Argument die Ereigniseingabe und das zweite Argument das Lambda-Kontextobjekt sein. Beide Argumente sind optional. Die folgenden sind beispielsweise ebenfalls gültige Lambda-Handler-Signaturen in C\$1:
+ `public async Task<string> HandleRequest()`
+ `public async Task<string> HandleRequest(Order order)`
+ `public async Task<string> HandleRequest(ILambdaContext context)`

Neben der Basissyntax der Handler-Signatur gibt es einige zusätzliche Einschränkungen:
+ Sie können das Schlüsselwort `unsafe` nicht in der Handler-Signatur verwenden. Sie können jedoch den `unsafe`-Kontext innerhalb der Handler-Methode und ihrer Abhängigkeiten verwenden. Weitere Informationen finden Sie unter [unsafe (C\$1-Referenz)](https://msdn.microsoft.com/en-us/library/chfa2zb8.aspx) auf der Microsoft-Dokumentationswebsite.
+ Der Handler darf das Schlüsselwort `params` nicht verwenden oder `ArgIterator` als Eingabe- oder Rückgabeparameter verwenden. Diese Schlüsselwörter unterstützen eine variable Anzahl von Parametern. Ihr Handler kann maximal zwei Argumente akzeptieren.
+ Der Handler ist möglicherweise keine generische Methode. Mit anderen Worten: Er kann keine generischen Typparameter wie `<T>` verwenden.
+ Lambda unterstützt keine asynchronen Handler mit `async void` in der Signatur.

## Namenskonventionen für Handler
<a name="csharp-handler-naming"></a>

Lambda-Handler in C\$1 haben keine strengen Benennungsbeschränkungen. Sie müssen jedoch sicherstellen, dass Sie Lambda bei der Bereitstellung Ihrer Funktion die richtige Handler-Zeichenfolge zur Verfügung stellen. Die richtige Handler-Zeichenfolge hängt davon ab, ob Sie einen [Klassenbibliotheks-Handler](#csharp-class-library-handlers) oder einen [Handler für ausführbare Assemblys](#csharp-executable-assembly-handlers) bereitstellen.

Sie können zwar einen beliebigen Namen für Ihren Handler verwenden, Funktionsnamen in C\$1 sind jedoch generell in. PascalCase Auch wenn der Dateiname nicht mit dem Klassennamen oder dem Handler-Namen übereinstimmen muss, ist es im Allgemeinen eine bewährte Methode, einen Dateinamen wie `OrderHandler.cs` zu verwenden, wenn der Klassenname `OrderHandler` lautet. Sie können den Dateinamen in diesem Beispiel beispielsweise von `Function.cs` in `OrderHandler.cs` ändern.

## Serialisierung in C\$1-Lambda-Funktionen
<a name="csharp-handler-serializer"></a>

JSON ist das gebräuchlichste und standardmäßigste Eingabeformat für Lambda-Funktionen. In diesem Beispiel erwartet die Funktion eine Eingabe ähnlich der folgenden:

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

In C\$1 können Sie die Form des erwarteten Eingabeereignisses in einer Klasse definieren. In diesem Beispiel definieren wir die `Order`-Klasse, um diese Eingabe zu modellieren:

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

Wenn Ihre Lambda-Funktion andere Eingabe- oder Ausgabetypen als ein `Stream`-Objekt verwendet, müssen Sie eine Serialisierungsbibliothek zu Ihrer Anwendung hinzufügen. Auf diese Weise können Sie die JSON-Eingabe in eine Instanz der von Ihnen definierten Klasse konvertieren. Es gibt zwei Methoden der Serialisierung für C\$1-Funktionen in Lambda: reflexionsbasierte Serialisierung und quellgenerierte Serialisierung.

### Reflexionsbasierte Serialisierung
<a name="csharp-reflection-based-serialization"></a>

AWS stellt vorgefertigte Bibliotheken bereit, die Sie schnell zu Ihrer Anwendung hinzufügen können. Diese Bibliotheken implementieren Serialisierung mithilfe von [Reflexion](https://learn.microsoft.com/en-us/dotnet/csharp/advanced-topics/reflection-and-attributes/). Verwenden Sie eins der folgenden Pakete, um die reflexionsbasierte Serialisierung zu implementieren:
+ `Amazon.Lambda.Serialization.SystemTextJson`: Im Backend nutzt dieses Paket `System.Text.Json` zur Ausführung von Serialisierungsaufgaben.
+ `Amazon.Lambda.Serialization.Json`: Im Backend nutzt dieses Paket `Newtonsoft.Json` zur Ausführung von Serialisierungsaufgaben.

Sie können auch Ihre eigene Serialisierungsbibliothek erstellen, indem Sie die `ILambdaSerializer`-Schnittstelle implementieren; diese ist als Teil der `Amazon.Lambda.Core`-Bibliothek verfügbar. Diese Schnittstelle definiert zwei Methoden:
+ `T Deserialize<T>(Stream requestStream);`

  Sie implementieren diese Methode für die Deserialisierung der Anfragenutzlast von der `Invoke`-API in das Objekt, das Ihrem Lambda-Funktions-Handler übergeben wird.
+ `T Serialize<T>(T response, Stream responseStream);`

  Sie implementieren diese Methode, um das von Ihrem Lambda-Funktions-Handler zurückgegebene Ergebnis in die Antwort-Nutzlast zu serialisieren, die der `Invoke`-API-Vorgang zurückgibt.

Das Hauptbeispiel auf dieser Seite verwendet reflexionsbasierte Serialisierung. Die auf Reflection basierende Serialisierung ist sofort einsatzbereit AWS Lambda und erfordert keine zusätzliche Einrichtung, weshalb sie aus Gründen der Einfachheit eine gute Wahl ist. Es ist jedoch mehr Funktionsspeicher erforderlich. Aufgrund von Laufzeitreflexionen kann es auch zu höheren Funktionslatenzen kommen.

### Quellgenerierte Serialisierung
<a name="csharp-source-generated-serialization"></a>

Bei der quellgenerierten Serialisierung wird der Serialisierungscode zur Kompilierzeit generiert. Dies macht Reflexion überflüssig und kann die Leistung Ihrer Funktion verbessern. Gehen Sie wie folgt vor, um die quellgenerierte Serialisierung in Ihrer Funktion zu verwenden:
+ Erstellen Sie eine neue Teilklasse, die von `JsonSerializerContext` erbt, und fügen Sie `JsonSerializable`-Attribute für alle Typen hinzu, die serialisiert oder deserialisiert werden müssen.
+ Konfigurieren Sie das `LambdaSerializer` so, dass es ein `SourceGeneratorLambdaJsonSerializer<T>` verwendet.
+ Aktualisieren Sie alle manuellen Serialisierungen und Deserialisierungen in Ihrem Anwendungscode, um die neu erstellte Klasse zu verwenden.

Das folgende Beispiel zeigt, wie Sie das Hauptbeispiel auf dieser Seite, das reflexionsbasierte Serialisierung verwendet, so ändern können, dass stattdessen die quellgenerierte Serialisierung verwendet wird.

```
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);
    
    ...
    
    }

}
```

Für die quellgenerierte Serialisierung sind mehr Einrichtungsschritte erforderlich als für die reflexionsbasierte Serialisierung. Funktionen, die quellgenerierte Serialisierung verwenden, verbrauchen jedoch tendenziell weniger Speicher und weisen aufgrund der Codegenerierung während der Kompilierung eine bessere Leistung auf. Um [Kaltstarts](lambda-runtime-environment.md#cold-start-latency) von Funktionen zu vermeiden, sollten Sie in Erwägung ziehen, zur quellgenerierten Serialisierung zu wechseln.

**Anmerkung**  
Wenn Sie die native [ahead-of-time Kompilierung (AOT)](dotnet-native-aot.md) mit Lambda verwenden möchten, müssen Sie die quellengenerierte Serialisierung verwenden.

## Dateibasierte Funktionen
<a name="csharp-file-based-functions"></a>

Mit dateibasierten Apps, die in .NET 10 eingeführt wurden, können Sie.NET-Anwendungen aus einer einzigen `.cs` Datei ohne Datei- oder Verzeichnisstruktur `.csproj` erstellen. Lambda unterstützt dateibasierte Funktionen, beginnend mit.NET 10. Sie bieten eine optimierte, einfache Möglichkeit, Lambda-Funktionen in C\$1 zu erstellen.

Der schnellste Weg, um mit der Erstellung einer auf C\$1-Dateien basierenden Lambda-Funktion zu beginnen, ist die Verwendung des Pakets. `Amazon.Lambda.Templates` Zur Installation dieses Pakets führen Sie den folgenden Befehl aus:

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

Erstellen Sie als Nächstes eine auf einer C\$1-Datei basierende Lambda-Beispielfunktion:

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

[Dateibasierte Funktionen verwenden ausführbare Assembly-Handler.](#csharp-executable-assembly-handlers) Sie müssen daher das `Amazon.Lambda.RuntimeSupport` NuGet Paket einschließen und die `LambdaBootstrapBuilder.Create` Methode verwenden, um die .NET-Handlerfunktion für den Ereignistyp zu registrieren und den.NET Lambda-Runtime-Client zu starten.

Dateibasierte Funktionen verwenden standardmäßig .NET Native AOT, was eine quellengenerierte Serialisierung erfordert. Sie können Native AOT deaktivieren, indem Sie es in Ihrer Quelldatei angeben. `#:property PublishAot=false` Weitere Informationen zur Verwendung von Native AOT in Lambda finden Sie unter. [Kompilieren Sie.NET-Lambda-Funktionscode in ein natives Laufzeitformat](dotnet-native-aot.md)

## Zugreifen auf und Verwenden des Lambda-Kontextobjekts
<a name="csharp-example-context"></a>

Das Lambda-[Kontextobjekt](csharp-context.md) enthält Informationen über Aufruf, Funktion und Ausführungsumgebung. In diesem Beispiel ist das Kontextobjekt vom Typ `Amazon.Lambda.Core.ILambdaContext` und das zweite Argument der Haupthandlerfunktion.

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

Das Kontextobjekt ist eine optionale Eingabe. Weitere Informationen zu gültigen akzeptierten Handlersignaturen finden Sie unter [Gültige Handler-Signaturen für C\$1-Funktionen](#csharp-handler-signatures).

Das Kontextobjekt ist nützlich, um Funktionsprotokolle für Amazon zu erstellen CloudWatch. Sie können die `context.getLogger()`-Methode verwenden, um ein `LambdaLogger`-Objekt für die Protokollierung abzurufen. In diesem Beispiel können wir den Logger verwenden, um eine Fehlermeldung zu protokollieren, falls bei der Verarbeitung aus irgendeinem Grund ein Fehler auftritt:

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

Außerhalb der Protokollierung können Sie das Kontextobjekt auch für die Funktionsüberwachung verwenden. Weitere Informationen über das Kontextobjekt finden Sie unter [Verwenden des Lambda-Kontextobjekts zum Abrufen von C\$1-Funktionsinformationen](csharp-context.md).

## Verwenden Sie die SDK für .NET Version 3 in Ihrem Handler
<a name="csharp-example-sdk-usage"></a>

Oft verwenden Sie Lambda-Funktionen, um mit anderen AWS Ressourcen zu interagieren oder diese zu aktualisieren. Die einfachste Art, eine Schnittstelle zu diesen Ressourcen herzustellen, ist die Verwendung von SDK für .NET v3.

**Anmerkung**  
Die SDK für .NET (v2) ist veraltet. Wir empfehlen, nur Version 3 zu verwenden. SDK für .NET 

Mit dem folgenden `Amazon.Lambda.Tools`-Befehl können Sie Ihrem Projekt SDK-Abhängigkeiten hinzufügen:

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

Im Hauptbeispiel auf dieser Seite müssen wir beispielsweise die Amazon-S3-API verwenden, um einen Beleg in S3 hochzuladen. Wir können den SDK-Client für Amazon S3 mit dem folgenden Befehl importieren:

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

Dieser Befehl fügt die Abhängigkeit zu Ihrem Projekt hinzu. In der `.csproj`-Datei Ihres Projekts sollte außerdem eine Zeile ähnlich der folgenden angezeigt werden:

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

Importieren Sie dann die Abhängigkeiten direkt in Ihren C\$1-Code:

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

Der Beispielcode initialisiert dann wie folgt einen Amazon-S3-Client (unter Verwendung der [standardmäßigen Anbieterkette für Anmeldeinformationen](https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html)):

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

In diesem Beispiel haben wir unseren Amazon-S3-Client außerhalb der Haupt-Handler-Funktion initialisiert, um zu vermeiden, dass wir ihn bei jedem Aufruf unserer Funktion initialisieren müssen. Nachdem Sie Ihren SDK-Client initialisiert haben, können Sie ihn für die Interaktion mit anderen AWS Diensten verwenden. Der Beispielcode ruft die Amazon S3 `PutObject`-API wie folgt auf:

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

await s3Client.PutObjectAsync(putRequest);
```

## Zugriff auf Umgebungsvariablen
<a name="csharp-example-envvars"></a>

In Ihrem Handler-Code können Sie mithilfe der `System.Environment.GetEnvironmentVariable`-Methode auf beliebige [Umgebungsvariablen](configuration-envvars.md) verweisen. In diesem Beispiel verweisen wir mit den folgenden Codezeilen auf die definierte `RECEIPT_BUCKET`-Umgebungsvariable:

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

## Verwenden des globalen Zustands
<a name="csharp-handler-state"></a>

Lambda führt Ihren statischen Code und den Klassenkonstruktor während der [Initialisierungsphase](lambda-runtime-environment.md#runtimes-lifecycle-ib) aus, bevor Ihre Funktion zum ersten Mal aufgerufen wird. Ressourcen, die während der Initialisierung erstellt werden, bleiben zwischen Aufrufen im Speicher, sodass Sie sie nicht bei jedem Aufruf Ihrer Funktion neu erstellen müssen.

Im Beispielcode befindet sich der Initialisierungscode des S3-Clients außerhalb der Haupt-Handler-Methode. Die Laufzeit initialisiert den Client, bevor die Funktion ihr erstes Ereignis verarbeitet, was zu längeren Verarbeitungszeiten führen kann. Nachfolgende Ereignisse sind viel schneller, da Lambda den Client nicht erneut initialisieren muss.

## Vereinfachen Sie den Funktionscode mit dem Lambda Annotations Framework
<a name="csharp-handler-annotations"></a>

[Lambda Annotations](https://www.nuget.org/packages/Amazon.Lambda.Annotations) ist ein Framework für .NET 8, das das Schreiben von Lambda-Funktionen mit C\$1 vereinfacht. Das Annotations-Framework verwendet [Quellgeneratoren](https://learn.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/source-generators-overview), um Code zu generieren, der vom Lambda-Programmiermodell in den vereinfachten Code übersetzt wird. Mit dem Annotations-Framework können Sie einen Großteil des Codes in einer Lambda-Funktion ersetzen, die mit dem regulären Programmiermodell geschrieben wurde. Code, der mit dem Framework geschrieben wurde, verwendet einfachere Ausdrücke, sodass Sie sich auf Ihre Geschäftslogik konzentrieren können. Beispiele finden Sie unter [Amazon.Lambda.Annotations](https://www.nuget.org/packages/Amazon.Lambda.Annotations) in der NuGet-Dokumentation.

Ein Beispiel für eine vollständige Anwendung, die Lambda-Annotationen verwendet, finden Sie im [ PhotoAssetManager](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3/cross-service/PhotoAssetManager)Beispiel im `awsdocs/aws-doc-sdk-examples` GitHub Repository. Die Hauptdatei `Function.cs` im Verzeichnis `PamApiAnnotations` verwendet Lambda Annotations. Zum Vergleich: Das Verzeichnis `PamApi` enthält äquivalente Dateien, die mit dem regulären Lambda-Programmiermodell geschrieben wurden.

### Abhängigkeitsinjektion mit dem Lambda Annotations-Framework
<a name="csharp-handler-annotations-injection"></a>

Sie können auch das Lambda Annotations-Framework verwenden, um Ihren Lambda-Funktionen eine Dependency Injection hinzuzufügen, indem Sie die Syntax verwenden, mit der Sie vertraut sind. Wenn Sie einer `[LambdaStartup]`-Datei ein `Startup.cs`-Attribut hinzufügen, generiert das Lambda Annotations-Framework den erforderlichen Code zur Kompilierzeit.

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

Ihre Lambda-Funktion kann Dienste entweder durch Konstruktorinjektion oder durch Injektion in einzelne Methoden unter Verwendung des `[FromServices]`-Attributs injizieren.

```
[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);
    }
}
```

## Bewährte Codemethoden für C\$1-Lambda-Funktionen
<a name="csharp-best-practices"></a>

Halten Sie sich an die Richtlinien in der folgenden Liste, um beim Erstellen Ihrer Lambda-Funktionen die besten Codierungspraktiken anzuwenden:
+ **Trennen Sie den Lambda-Handler von Ihrer Core-Logik.** Auf diese Weise können Sie eine Funktion zur besseren Prüfbarkeit von Einheiten schaffen.
+ **Kontrollieren Sie die Abhängigkeiten im Bereitstellungspaket Ihrer Funktion. ** Die AWS Lambda -Ausführungsumgebung enthält eine Reihe von Bibliotheken. Um die neuesten Funktionen und Sicherheitsupdates zu aktivieren, wird Lambda diese Bibliotheken regelmäßig aktualisieren. Diese Updates können das Verhalten Ihrer Lambda-Funktion geringfügig verändern. Um die Abhängigkeiten, die Ihre Funktion verwendet, vollständig zu kontrollieren, empfehlen wir, alle Abhängigkeiten mit Ihrem Bereitstellungspaket zu bündeln. 
+ **Minimieren Sie die Komplexität Ihrer Abhängigkeiten.** Ziehen Sie einfachere Frameworks vor, die sich schnell beim Start der [Ausführungsumgebung](lambda-runtime-environment.md) laden lassen.
+ **Minimieren Sie die Größe Ihres Bereitstellungspakets auf die für die Laufzeit erforderliche Größe.** Dadurch verkürzt sich die Zeit, die für das Herunterladen und Entpacken Ihres Bereitstellungspakets vor dem Aufruf benötigt wird. Vermeiden Sie es bei in .NET verfassten Funktionen, die gesamte AWS SDK-Bibliothek als Teil Ihres Bereitstellungspakets hochzuladen. Stattdessen sollten Sie selektiv von den Modulen ausgehen, die Komponenten des SDK aufnehmen, die Sie benötigen (z. B. DynamoDB, Amazon-S3-SDK-Module und Lambda-Kernbibliotheken). 

**Nutzen Sie die Wiederverwendung der Ausführungsumgebung zur Verbesserung Ihrer Funktion.** Initialisieren Sie SDK-Clients und Datenbankverbindungen außerhalb des Funktions-Handlers und speichern Sie statische Komponenten lokal im `/tmp`-Verzeichnis. Nachfolgende Aufrufe, die von derselben Instance Ihrer Funktion verarbeitet werden, können diese Ressourcen wiederverwenden. Dies spart Kosten durch Reduzierung der Funktionslaufzeit.

Um potenzielle Datenlecks über Aufrufe hinweg zu vermeiden, verwenden Sie die Ausführungsumgebung nicht, um Benutzerdaten, Ereignisse oder andere Informationen mit Sicherheitsauswirkungen zu speichern. Wenn Ihre Funktion auf einem veränderbaren Zustand beruht, der nicht im Speicher innerhalb des Handlers gespeichert werden kann, sollten Sie für jeden Benutzer eine separate Funktion oder separate Versionen einer Funktion erstellen.

**Verwenden Sie eine Keep-Alive-Direktive, um dauerhafte Verbindungen zu pflegen.** Lambda bereinigt Leerlaufverbindungen im Laufe der Zeit. Der Versuch, eine Leerlaufverbindung beim Aufruf einer Funktion wiederzuverwenden, führt zu einem Verbindungsfehler. Um Ihre persistente Verbindung aufrechtzuerhalten, verwenden Sie die Keep-Alive-Direktive, die Ihrer Laufzeit zugeordnet ist. Ein Beispiel finden Sie unter [Wiederverwenden von Verbindungen mit Keep-Alive in Node.js](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html).

**Verwenden Sie [Umgebungsvariablen](configuration-envvars.md) um Betriebsparameter an Ihre Funktion zu übergeben.** Wenn Sie z. B. Daten in einen Amazon-S3-Bucket schreiben, anstatt den Bucket-Namen, in den Sie schreiben, hartzucodieren, konfigurieren Sie den Bucket-Namen als Umgebungsvariable.

**Vermeiden Sie rekursive Aufrufe** in Ihrer Lambda-Funktion, bei denen die Funktion sich selbst aufruft oder einen Prozess initiiert, der die Funktion erneut aufrufen kann. Dies kann zu unvorhergesehenen Mengen an Funktionsaufrufen führen und höhere Kosten zur Folge haben. Wenn Sie eine unbeabsichtigte Menge von Aufrufen feststellen, legen Sie die reservierte gleichzeitige Ausführung der Funktion auf `0` fest, um sofort alle Aufrufe der Funktion zu drosseln, während Sie den Code aktualisieren.

**Verwenden Sie APIs in Ihrem Lambda-Funktionscode nicht undokumentiert, nicht öffentlich**. Für AWS Lambda verwaltete Laufzeiten führt Lambda regelmäßig Sicherheits- und Funktionsupdates für interne Lambda-Laufzeiten durch. APIs Diese internen API-Updates können abwärtsinkompatibel sein, was zu unbeabsichtigten Folgen wie Aufruffehlern führen kann, wenn Ihre Funktion von diesen nicht öffentlichen Daten abhängig ist. APIs Eine Liste [der öffentlich verfügbaren Programme finden Sie in der API-Referenz.](https://docs.aws.amazon.com/lambda/latest/api/welcome.html) APIs

**Schreiben Sie idempotenten Code.** Das Schreiben idempotenter Code für Ihre Funktionen stellt sicher, dass doppelte Ereignisse auf die gleiche Weise behandelt werden. Ihr Code sollte Ereignisse ordnungsgemäß validieren und doppelte Ereignisse ordnungsgemäß behandeln. Weitere Informationen finden Sie unter [Wie mache ich meine Lambda-Funktion idempotent?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/).

# Erstellen und Bereitstellen von C\$1-Lambda-Funktionen mit ZIP-Dateiarchiven
<a name="csharp-package"></a>

Ein .NET-Bereitstellungspaket (ZIP-Dateiarchiv) enthält die kompilierten Assembly Ihrer Funktion sowie aller ihrer Assembly-Abhängigkeiten. Das Paket enthält auch eine `proj.deps.json`-Datei. Dies signalisiert der .NET-Laufzeit alle Abhängigkeiten Ihrer Funktion sowie eine `proj.runtimeconfig.json`-Datei, die für die Konfiguration der Laufzeit verwendet wird.

Um einzelne Lambda-Funktionen bereitzustellen, können Sie die `Amazon.Lambda.Tools` .NET Lambda Global CLI verwenden. Mit dem `dotnet lambda deploy-function` Befehl wird automatisch ein ZIP-Bereitstellungspaket erstellt und auf Lambda bereitgestellt. Wir empfehlen jedoch, Frameworks wie AWS Serverless Application Model (AWS SAM) oder AWS Cloud Development Kit (AWS CDK) zu verwenden, um Ihre .NET-Anwendungen auf AWS bereitzustellen.

Serverless-Anwendungen bestehen in der Regel aus einer Kombination von Lambda-Funktionen und anderen verwalteten AWS-Services, die zusammenarbeiten, um eine bestimmte Geschäftsaufgabe zu erfüllen. AWS SAM und AWS CDK vereinfachen die Erstellung und Bereitstellung von Lambda-Funktionen mit anderen AWS-Services in großem Umfang. Die [AWS SAM-Vorlagenspezifikation](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification.html) bietet eine einfache und saubere Syntax zur Beschreibung der Lambda-Funktionen, APIs, Berechtigungen, Konfigurationen und andere AWS-Ressourcen, aus denen Ihre Serverless-Anwendung besteht. Über das [AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/home.html) definieren Sie die Cloud-Infrastruktur als Code, mit dem Sie zuverlässige, skalierbare und kostengünstige Anwendungen in der Cloud mit modernen Programmiersprachen und Frameworks wie .NET erstellen können. Sowohl die AWS CDK als auch die AWS SAM verwenden das.NET Lambda Global CLI, um Ihre Funktionen zu verpacken.

Obwohl es möglich ist, [Lambda-Ebenen](chapter-layers.md) mit Funktionen in C\$1 [mithilfe der .NET-Core-CLI zu verwenden](csharp-package-cli.md#csharp-layers), raten wir davon ab. Funktionen in C\$1, die Ebenen verwenden, laden die freigegebenen Baugruppen während des [Init-Phase](lambda-runtime-environment.md#runtimes-lifecycle-ib) manuell in den Speicher, was die Kaltstartzeiten verlängern kann. Fügen Sie stattdessen den gesamten gemeinsam genutzten Code zur Kompilierungszeit ein, um die Auswirkungen auf die Leistung durch das Laden von Assemblys zur Laufzeit zu vermeiden.

In den folgenden Abschnitten finden Sie Anweisungen zum Erstellen und Bereitstellen von .NET-Lambda-Funktionen mit der AWS SAM, der AWS CDK und der .NET Lambda Global CLI.

**Topics**
+ [

# Verwenden der.NET Lambda Global CLI
](csharp-package-cli.md)
+ [

# Bereitstellen von C\$1-Lambda-Funktionen mit AWS SAM
](csharp-package-sam.md)
+ [

# Bereitstellen von C\$1-Lambda-Funktionen mit AWS CDK
](csharp-package-cdk.md)
+ [

# ASP.NET-Anwendungen bereitstellen
](csharp-package-asp.md)

# Verwenden der.NET Lambda Global CLI
<a name="csharp-package-cli"></a>

Die .NET-CLI und die Erweiterung .NET Lambda Global Tools (`Amazon.Lambda.Tools`) bieten eine plattformübergreifende Möglichkeit, .NET-basierte Lambda-Anwendungen zu erstellen, zu verpacken und für Lambda bereitzustellen. In diesem Abschnitt erfahren Sie, wie Sie neue Lambda .NET-Projekte mit den .NET CLI- und Amazon Lambda-Vorlagen erstellen und diese mithilfe von `Amazon.Lambda.Tools` verpacken und bereitstellen

**Topics**
+ [

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

## .NET-Projekte mit der .NET-CLI erstellen
](#csharp-package-cli-create)
+ [

## .NET-Projekte über die .NET-CLI bereitstellen
](#csharp-package-cli-deploy)
+ [

## Verwendung von Lambda-Ebenen mit der.NET-CLI
](#csharp-layers)

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

**.NET 8-SDK**  
Falls Sie das noch nicht getan haben, installieren Sie das [.NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0)-SDK und Laufzeit.

**AWS Amazon.Lambda.Templates .NET-Projektvorlagen**  
Verwenden Sie das [https://www.nuget.org/packages/Amazon.Lambda.Templates](https://www.nuget.org/packages/Amazon.Lambda.Templates)-NuGet-Paket, um Ihren Lambda-Funktionscode zu generieren. Zur Installation dieses Vorlagenpakets führen Sie den folgenden Befehl aus:  

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

**AWS Amazon.Lambda.Tools .NET Global CLI-Tools**  
Verwenden Sie zum Erstellen Ihrer Lambda-Funktionen die [https://www.nuget.org/packages/Amazon.Lambda.Tools](https://www.nuget.org/packages/Amazon.Lambda.Tools)-[.NET Global Tools-Erweiterung](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/). Um Amazon.Lambda.Tools zu installieren, führen Sie den folgenden Befehl aus:  

```
dotnet tool install -g Amazon.Lambda.Tools
```
Weitere Informationen über die Amazon.Lambda.Tools .NET CLI-Erweiterung finden Sie im [AWS-Erweiterungen für .NET-CLI](https://github.com/aws/aws-extensions-for-dotnet-cli)-Repository auf GitHub.

## .NET-Projekte mit der .NET-CLI erstellen
<a name="csharp-package-cli-create"></a>

Verwenden Sie in der .NET CLI den `dotnet new`-Befehl zum Erstellen von .NET-Projekten in der Befehlszeile. Lambda bietet mithilfe des [https://www.nuget.org/packages/Amazon.Lambda.Templates](https://www.nuget.org/packages/Amazon.Lambda.Templates)-NuGet-Pakets zusätzliche Vorlagen an.

Nach der Installation des Pakets führen Sie den folgenden Befehl aus, um eine Liste des verfügbaren Vorlagen zu sehen.

```
dotnet new list
```

Wenn Sie Details zu einer Vorlage einsehen möchten, verwenden Sie die `help`-Option. Um beispielsweise Details über die `lambda.EmptyFunction`-Vorlage zu sehen, führen Sie den folgenden Befehl aus.

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

Verwenden Sie die `lambda.EmptyFunction`-Vorlage, um eine Basisvorlage für eine .NET-Lambda-Funktion zu erstellen. Dadurch wird eine einfache Funktion erstellt, die eine Zeichenfolge als Eingabe verwendet und diese mithilfe der `ToUpper`-Methode in Großbuchstaben umwandelt. Diese Vorlage unterstützt die folgenden Optionen. 
+ `--name` – Der Name der Funktion.
+ `--region` – Die AWS-Region, in der die Funktion erstellt werden soll.
+ `--profile` – Der Name eines Profils in Ihrer AWS SDK für .NET-Anmeldeinformationsdatei. Weitere Informationen zu Anmeldeinformationsprofilen in.NET findenSie unter [AWS-Anmeldeinformation konfigurieren](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html) im *AWS-SDK für .NET Entwicklerhandbuch*.

In diesem Beispiel erstellen wir eine neue leere Funktion mit dem Namen `myDotnetFunction` unter Verwendung des Standardprofils und der AWS-Region-Einstellungen:

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

Mit diesem Befehl werden die folgenden Dateien und Verzeichnisse in Ihrem Projektverzeichnis erstellt.

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

Zeigen Sie im Verzeichnis `src/myDotnetFunction` die folgenden Dateien an:
+ **aws-lambda-tools-defaults.json**: Hier geben Sie die Befehlszeilenoptionen an, wenn Sie Ihre Lambda-Funktion bereitstellen. Zum Beispiel:

  ```
    "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**: Der Funktionscode Ihres Lambda-Handlers. Dies ist eine C \$1-Vorlage mit der `Amazon.Lambda.Core`-Standardbibliothek und einem `LambdaSerializer`-Standardattribut. Weitere Informationen zu den Serialisierungsanforderungen und -optionen finden Sie unter [Serialisierung in C\$1-Lambda-Funktionen](csharp-handler.md#csharp-handler-serializer). Es ist auch eine Beispielfunktion enthalten, die Sie bearbeiten können, um Lambda-Funktionscode anzuwenden.

  ```
  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**: Eine [MSBuild](https://msdn.microsoft.com/en-us/library/dd393574.aspx)-Datei, in der die Dateien und Assemblys aufgeführt werden, aus denen Ihre Anwendung besteht.

  ```
  <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**: Verwenden Sie diese Datei, um Ihre Lambda-Funktion zu dokumentieren.

Zeigen Sie im Verzeichnis `myfunction/test` die folgenden Dateien an:
+ **myDotnetFunction.Tests.csproj**: Wie bereits erwähnt, handelt es sich hierbei um eine [MSBuild](https://msdn.microsoft.com/en-us/library/dd393574.aspx)-Datei, in der die Dateien und Assembys aufgeführt werden, aus denen Ihr Testprojekt besteht. Beachten Sie auch, dass die `Amazon.Lambda.Core`-Bibliothek enthalten ist. Damit können Sie nahtlos beliebige Lambda-Vorlagen integrieren, die zum Testen Ihrer Funktion erforderlich sind.

  ```
  <Project Sdk="Microsoft.NET.Sdk">
     ... 
  
      <PackageReference Include="Amazon.Lambda.Core" Version="2.2.0 " />
     ...
  ```
+ **FunctionTest.cs**: Die gleiche C \$1 -Vorlagendatei, die sich im `src`-Verzeichnis befindet. Bearbeiten Sie diese Datei, damit sie dem Produktionscode Ihrer Funktion gleicht, und testen Sie sie vor dem Hochladen Ihrer Lambda-Funktion in eine Produktionsumgebung.

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

## .NET-Projekte über die .NET-CLI bereitstellen
<a name="csharp-package-cli-deploy"></a>

Um Ihr Bereitstellungspaket zu erstellen und es auf Lambda bereitzustellen, verwenden Sie die `Amazon.Lambda.Tools`-CLI-Tools. Um Ihre Funktion anhand der Dateien bereitzustellen, die Sie in den vorherigen Schritten erstellt haben, navigieren Sie zunächst zu dem Ordner, der die `.csproj`-Datei Ihrer Funktion enthält.

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

Führen Sie den folgenden Befehl aus, um Ihren Code als ZIP-Bereitstellungspaket für Lambda bereitzustellen. Wählen Sie Ihren eigenen Funktionsnamen.

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

Während der Bereitstellung fordert Sie der Assistent auf, einen [Definieren von Lambda-Funktionsberechtigungen mit einer Ausführungsrolle](lambda-intro-execution-role.md) auszuwählen. Wählen Sie für dieses Beispiel die `lambda_basic_role`.

Nachdem Sie Ihre Funktion bereitgestellt haben, können Sie sie mit dem `dotnet lambda invoke-function`-Befehl in der Cloud testen. Für den Beispielcode in der `lambda.EmptyFunction`-Vorlage können Sie Ihre Funktion testen, indem Sie mit der `--payload`-Option eine Zeichenfolge übergeben.

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

Wenn Ihre Funktion erfolgreich bereitgestellt wurde, sollten Sie eine Ausgabe ähnlich der folgenden sehen.

```
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
```

## Verwendung von Lambda-Ebenen mit der.NET-CLI
<a name="csharp-layers"></a>

**Anmerkung**  
Es ist zwar möglich, [Ebenen](chapter-layers.md) mit Funktionen in .NET zu verwenden, wir raten jedoch davon ab. Funktionen in .NET, die Ebenen verwenden, laden die gemeinsam genutzten Assemblys während der `Init`-Phase manuell in den Speicher, was die Kaltstartzeiten verlängern kann. Schließen Sie stattdessen den gesamten freigegebenen Code zur Kompilierzeit ein, um die integrierten Optimierungen des .NET-Compilers zu nutzen.

Die .NET-CLI unterstützt Befehle, mit denen Sie Ebenen veröffentlichen und C\$1-Funktionen bereitstellen können, die Ebenen nutzen. Um eine Ebene in einem angegebenen Amazon-S3-Bucket zu veröffentlichen, führen Sie den folgenden Befehl im selben Verzeichnis wie Ihre `.csproj`-Datei aus:

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

Wenn Sie dann Ihre Funktion mithilfe der .NET-CLI bereitstellen, geben Sie im folgenden Befehl den Ebenen-ARN an, den Sie verwenden wollen:

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

Ein vollständiges Beispiel einer Hello-World-Funktion finden Sie im Beispiel [blank-csharp-with-layer](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-csharp-with-layer).

# Bereitstellen von C\$1-Lambda-Funktionen mit AWS SAM
<a name="csharp-package-sam"></a>

Das AWS Serverless Application Model (AWS SAM) ist ein Toolkit, das den Prozess der Erstellung und Ausführung von Serverless-Anwendungen auf AWS optimiert. Sie definieren die Ressourcen für Ihre Anwendung in einer YAML- oder JSON-Vorlage und verwenden die AWS SAM-Befehlszeilenschnittstelle (AWS SAM CLI), um Ihre Anwendungen zu erstellen, zu verpacken und bereitzustellen. Wenn Sie eine Lambda-Funktion aus einer AWS SAM-Vorlage erstellen, erstellt AWS SAM automatisch ein ZIP-Bereitstellungspaket oder ein Container-Image mit Ihrem Funktionscode und allen von Ihnen angegebenen Abhängigkeiten. AWS SAM setzt dann Ihre Funktion mit Hilfe eines [CloudFormation-Stacks](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacks.html) ein. Weitere Informationen zur Verwendung von AWS SAM für die Erstellung und Bereitstellung von Lambda-Funktionen finden Sie unter [Erste Schritte mit AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started.html) im *AWS Serverless Application Model-Entwicklerhandbuch*.

Die folgenden Schritte zeigen Ihnen, wie Sie eine .NET Hello World-Beispielanwendung mit AWS SAM herunterladen, erstellen und bereitstellen können. Diese Beispielanwendung verwendet eine Lambda-Funktion und einen Amazon API Gateway-Endpunkt, um ein grundlegendes API-Backend zu implementieren. Wenn Sie eine HTTP GET-Anforderung an Ihren API Gateway-Endpunkt senden, ruft API Gateway Ihre Lambda-Funktion auf. Die Funktion gibt eine „Hello World“ -Meldung zusammen mit der IP-Adresse der Lambda-Funktionsinstance zurück, die Ihre Anfrage verarbeitet.

Wenn Sie Ihre Anwendung mithilfe von AWS SAM erstellen und bereitstellen, verwendet die AWS SAM-CLI hinter den Kulissen den Befehl `dotnet lambda package`, um die einzelnen Lambda-Funktions-Codebündel zu verpacken.

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

**.NET 8-SDK**  
Installieren Sie das [.NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0)-SDK und Runtime.

**AWS SAM-CLI-Version 1.39 oder höher**  
Wie Sie die neueste Version der AWS SAM-CLI installieren können, erfahren Sie unter [Installation der AWS SAM-CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html).

## Bereitstellen einer AWS SAM-Beispielanwendung
<a name="csharp-package-sam-deploy"></a>

1. Initialisieren Sie die Anwendung mit der Hello World-.NET-Vorlage mit dem folgenden Befehl.

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

   Mit diesem Befehl werden die folgenden Dateien und Verzeichnisse in Ihrem Projektverzeichnis erstellt.

   ```
   └── 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. Navigieren Sie in das Verzeichnis, das die `template.yaml file` enthält. Diese Datei ist eine Vorlage, die die AWS-Ressourcen für Ihre Anwendung definiert, einschließlich Ihrer Lambda-Funktion und einer API-Gateway-API.

   ```
   cd sam-app
   ```

1. Um den Quellcode Ihrer Anwendung zu erstellen, führen Sie folgenden Befehl aus.

   ```
   sam build
   ```

1. Führen Sie den folgenden Befehl aus, um Ihre Anwendung auf AWS bereitzustellen.

   ```
   sam deploy --guided
   ```

   Dieser Befehl packt Ihre Anwendung und stellt sie mit der folgenden Reihe von Eingabeaufforderungen bereit. Um die Standardoptionen zu übernehmen, drücken Sie die Eingabetaste.
**Anmerkung**  
Für **HelloWorldFunction ist möglicherweise keine Autorisierung definiert. Ist das in Ordnung?**, stellen Sie sicher, dass Sie `y` eingeben.
   + **Stack-Name**: Der Name des Stacks, der in CloudFormation bereitgestellt werden soll. Dieser Name muss für Ihr AWS-Konto und AWS-Region eindeutig sein.
   + **AWS-Region**: Die AWS-Region, in der Sie Ihre Anwendung bereitstellen möchten.
   + **Änderungen vor der Bereitstellung bestätigen**: Wählen Sie Ja, um alle Änderungssätze manuell zu überprüfen, bevor AWS SAM die Anwendungsänderungen bereitstellt. Wenn Sie nein wählen, werden Anwendungsänderungen automatisch von der AWS SAM CLI bereitgestellt.
   + **Erlauben Sie die Erstellung von SAM-CLI-IAM-Rollen**: Viele AWS SAM-Vorlagen, einschließlich der Hello world-Vorlage in diesem Beispiel, erstellen AWS Identity and Access Management (IAM)-Rollen, um Ihren Lambda-Funktionen die Berechtigung zum Zugriff auf andere AWS-Services zu geben. Wählen Sie Ja, um die Berechtigung zur Bereitstellung eines CloudFormation-Stacks zu erteilen, der IAM-Rollen erstellt oder ändert.
   + **Rollback deaktivieren**: Wenn AWS SAM bei der Erstellung oder Bereitstellung Ihres Stacks auf einen Fehler stößt, wird der Stack standardmäßig auf die vorherige Version zurückgesetzt. Wählen Sie Nein, um diese Standardeinstellung zu akzeptieren.
   + **HelloWorldFunction hat möglicherweise keine Berechtigung definiert, ist dies in Ordnung**: Geben Sie `y` ein.
   + **Argumente in samconfig.toml speichern**: Wählen Sie Ja, um Ihre Konfigurationsauswahl zu speichern. In Zukunft können Sie `sam deploy` ohne Parameter erneut ausführen, um Änderungen an Ihrer Anwendung vorzunehmen.

1. Wenn die Bereitstellung Ihrer Anwendung abgeschlossen ist, gibt die CLI den Amazon Resource Name (ARN) der Hello World Lambda-Funktion und die für sie erstellte IAM-Rolle zurück. Sie zeigt auch den Endpunkt Ihrer API-Gateway-API an. Um Ihre Anwendung zu testen, öffnen Sie den Endpunkt in einem Browser. Es wird eine Antwort ähnlich der folgenden angezeigt.

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

1. Um Ihre Ressourcen zu löschen, führen Sie den folgenden Befehl aus. Beachten Sie, dass der von Ihnen erstellte API-Endpunkt ein öffentlicher Endpunkt ist, auf den über das Internet zugegriffen werden kann. Es wird empfohlen, dass Sie diesen Endpunkt nach dem Testen löschen.

   ```
   sam delete
   ```

## Nächste Schritte
<a name="csharp-package-sam-next"></a>

Weitere Informationen über die Verwendung von AWS SAM zur Erstellung und Bereitstellung von Lambda-Funktionen mit .NET finden Sie in den folgenden Ressourcen:
+ Das [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)
+ [Serverless .NET-Anwendungen mit AWS Lambda und der SAM-CLI](https://aws.amazon.com/blogs/dotnet/building-serverless-net-applications-with-aws-lambda-and-the-sam-cli/)

# Bereitstellen von C\$1-Lambda-Funktionen mit AWS CDK
<a name="csharp-package-cdk"></a>

Das AWS Cloud Development Kit (AWS CDK) ist ein Open-Source-Framework für die Softwareentwicklung zur Definition von Cloud-Infrastrukturen als Code mit modernen Programmiersprachen und Frameworks wie .NET. AWS CDK-Projekte werden ausgeführt, um CloudFormation-Vorlagen zu generieren, die dann für die Bereitstellung Ihres Codes verwendet werden.

Befolgen Sie die Anweisungen in den folgenden Abschnitten, um eine Hello world .NET-Beispielanwendung mit dem AWS CDK zu erstellen und bereitzustellen. Die Beispielanwendung implementiert ein grundlegendes API-Backend, das aus einem API-Gateway-Endpunkt und einer Lambda-Funktion besteht. API Gateway ruft die Lambda-Funktion auf, wenn Sie eine HTTP-GET-Anforderung an den Endpunkt senden. Die Funktion gibt eine Hello-World-Nachricht zusammen mit der IP-Adresse der Lambda-Instance zurück, die Ihre Anfrage verarbeitet.

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

**.NET 8-SDK**  
Installieren Sie das [.NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0)-SDK und Runtime.

**AWS CDK Version 2**  
Informationen zur Installation der neuesten Version von AWS CDK finden Sie unter [Erste Schritte mit AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html) im *AWS Cloud Development Kit (AWS CDK)-v2-Entwicklerhandbuch*.

## Bereitstellen einer AWS CDK-Beispielanwendung
<a name="csharp-package-cdk-deploy"></a>

1. Erstellen Sie ein Projektverzeichnis für die Beispielanwendung und navigieren Sie dorthin.

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

1. Initialisieren Sie eine neue AWS CDK-Anwendung, indem Sie den folgenden Befehl ausführen.

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

   Der Befehl erstellt die folgenden Dateien und Verzeichnisse in Ihrem Projektverzeichnis

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

1. Öffnen Sie das `src`-Verzeichnis und erstellen Sie eine neue Lambda-Funktion mit der.NET-CLI. Dies ist die Funktion, die Sie mit dem AWS CDK einsetzen werden. In diesem Beispiel erstellen Sie eine Hello world-Funktion mit dem Namen `HelloWorldLambda` unter Verwendung der `lambda.EmptyFunction`-Vorlage.

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

   Nach diesem Schritt sollte Ihre Verzeichnisstruktur innerhalb Ihres Projektverzeichnisses wie folgt aussehen.

   ```
   ├── 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. Öffnen Sie die `HelloWorldStack.cs`-Datei aus dem Verzeichnis `src/HelloWorld`. Ersetzen Sie den Inhalt der Datei durch den folgenden Code.

   ```
   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
                   }),
               });
           }
       }
   }
   ```

   Dies ist der Code zum Kompilieren und Bündeln des Anwendungscodes sowie die Definition der Lambda-Funktion selbst. Mit dem `BundlingOptions`-Objekt kann eine Zip-Datei erstellt werden, zusammen mit einer Reihe von Befehlen, die zur Erzeugung des Inhalts der Zip-Datei verwendet werden. In diesem Fall wird der Befehl `dotnet lambda package` zum Kompilieren und Erzeugen der Zip-Datei verwendet.

1. Um Ihre Anwendung bereitzustellen, führen Sie den folgenden Befehl aus.

   ```
   cdk deploy
   ```

1. Rufen Sie Ihre bereitgestellte Lambda-Funktion mit der .NET Lambda CLI auf.

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

1. Nach Abschluss der Tests können Sie die erstellten Ressourcen löschen, es sei denn, Sie möchten sie beibehalten. Führen Sie den folgenden Befehl aus, um Ihre Ressourcen zu löschen.

   ```
   cdk destroy
   ```

## Nächste Schritte
<a name="csharp-package-cdk-next"></a>

Weitere Informationen über die Verwendung von AWS CDK zur Erstellung und Bereitstellung von Lambda-Funktionen mit .NET finden Sie in den folgenden Ressourcen:
+ [Arbeiten mit AWS-CDK in C\$1](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-csharp.html)
+ [Erstellen, Verpacken und Veröffentlichen von .NET-C\$1-Lambda-Funktionen mit dem CDK AWS](https://aws.amazon.com/blogs/modernizing-with-aws/build-package-publish-dotnet-csharp-lambda-functions-aws-cdk/)

# ASP.NET-Anwendungen bereitstellen
<a name="csharp-package-asp"></a>

Sie können nicht nur ereignisgesteuerte Funktionen hosten, sondern auch .NET mit Lambda verwenden, um leichtgewichtige ASP.NET-Anwendungen zu hosten. Sie können ASP.NET-Anwendungen mithilfe des `Amazon.Lambda.AspNetCoreServer`-NuGet-Pakets erstellen und bereitstellen. In diesem Abschnitt erfahren Sie, wie Sie eine ASP.NET-Web-API mit dem .NET Lambda CLI-Tooling in Lambda bereitstellen.

**Topics**
+ [

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

## Eine ASP.NET-Web-API für Lambda bereitstellen
](#csharp-package-asp-deploy-api)
+ [

## Bereitstellung minimaler ASP.NET-APIs für Lambda
](#csharp-package-asp-deploy-minimal)

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

**.NET 8-SDK**  
Installieren Sie das [.NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0)-SDK und ASP.NET Core Runtime.

**Amazon.Lambda.Tools**  
Verwenden Sie zum Erstellen Ihrer Lambda-Funktionen die [https://www.nuget.org/packages/Amazon.Lambda.Tools](https://www.nuget.org/packages/Amazon.Lambda.Tools)-[.NET Global Tools-Erweiterung](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/). Um Amazon.Lambda.Tools zu installieren, führen Sie den folgenden Befehl aus:  

```
dotnet tool install -g Amazon.Lambda.Tools
```
Weitere Informationen über die Amazon.Lambda.Tools .NET CLI-Erweiterung finden Sie im [AWS-Erweiterungen für .NET-CLI](https://github.com/aws/aws-extensions-for-dotnet-cli)-Repository auf GitHub.

**Amazon.Lambda.Templates**  
Verwenden Sie das [https://www.nuget.org/packages/Amazon.Lambda.Templates](https://www.nuget.org/packages/Amazon.Lambda.Templates)-NuGet-Paket, um Ihren Lambda-Funktionscode zu generieren. Zur Installation dieses Vorlagenpakets führen Sie den folgenden Befehl aus:  

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

## Eine ASP.NET-Web-API für Lambda bereitstellen
<a name="csharp-package-asp-deploy-api"></a>

Um eine Web-API mit ASP.NET bereitzustellen, können Sie die .NET-Lambda-Vorlagen verwenden, um ein neues Web-API-Projekt zu erstellen. Verwenden Sie den folgenden Befehl, um ein neues ASP.NET-Web-API-Projekt zu initialisieren. Im Beispielbefehl nennen wir das Projekt `AspNetOnLambda`.

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

Mit diesem Befehl werden die folgenden Dateien und Verzeichnisse in Ihrem Projektverzeichnis erstellt.

```
.
└── 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
```

Wenn Lambda Ihre Funktion aufruft, wird als Einstiegspunkt die Datei `LambdaEntryPoint.cs` verwendet. Die von der .NET Lambda-Vorlage erstellte Datei enthält den folgenden Code.

```
namespace AspNetOnLambda;

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

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

Der von Lambda verwendete Einstiegspunkt muss von einer der drei Basisklassen im Paket `Amazon.Lambda.AspNetCoreServer` erben. Diese drei Basisklassen sind:
+ `APIGatewayProxyFunction`
+ `APIGatewayHttpApiV2ProxyFunction`
+ `ApplicationLoadBalancerFunction`

Die Standardklasse, die verwendet wird, wenn Sie Ihre `LambdaEntryPoint.cs`-Datei mit der bereitgestellten .NET Lambda-Vorlage erstellen, ist `APIGatewayProxyFunction`. Die Basisklasse, die Sie in Ihrer Funktion verwenden, hängt davon ab, welche API-Schicht vor Ihrer Lambda-Funktion steht.

Jede der drei Basisklassen enthält eine öffentliche Methode namens `FunctionHandlerAsync`. Der Name dieser Methode wird Teil der [Handler-String](csharp-handler.md#csharp-class-library-handlers) sein, die Lambda verwendet, um Ihre Funktion aufzurufen. Die `FunctionHandlerAsync`-Methode wandelt den eingehenden Ereignis-Payload in das korrekte ASP.NET-Format und die ASP.NET-Antwort zurück in einen Lambda-Antwort-Payload um. Für das gezeigte Beispielprojekt `AspNetOnLambda` würde der Handler-String wie folgt lauten.

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

Um die API in Lambda bereitzustellen, führen Sie die folgenden Befehle aus, um in das Verzeichnis mit Ihrer Quellcodedatei zu navigieren und Ihre Funktion mit CloudFormation bereitzustellen.

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

**Tipp**  
Wenn Sie eine API mit dem Befehl `dotnet lambda deploy-serverless` bereitstellen, gibt CloudFormation Ihrer Lambda-Funktion einen Namen, der auf dem Stapelnamen basiert, den Sie während der Bereitstellung angeben. Um Ihrer Lambda-Funktion einen benutzerdefinierten Namen zu geben, bearbeiten Sie die `serverless.template`-Datei, um der `AWS::Serverless::Function`-Ressource eine `FunctionName`-Eigenschaft hinzuzufügen. Weitere Informationen finden Sie unter [Namenstyp](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-name.html) im *CloudFormation-Benutzerhandbuch*.

## Bereitstellung minimaler ASP.NET-APIs für Lambda
<a name="csharp-package-asp-deploy-minimal"></a>

Um eine ASP.NET-Minimal-API für Lambda bereitzustellen, können Sie die .NET-Lambda-Vorlagen verwenden, um ein neues Minimal-API-Projekt zu erstellen. Verwenden Sie den folgenden Befehl, um ein neues minimales API-Projekt zu initialisieren. In diesem Beispiel nennen wir das Projekt `MinimalApiOnLambda`.

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

Der Befehl erstellt die folgenden Dateien und Verzeichnisse in Ihrem Projektverzeichnis.

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

Die Datei `Program.cs` enthält den folgenden Code.

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

Um Ihre Minimal-API für die Ausführung auf Lambda zu konfigurieren, müssen Sie diesen Code möglicherweise bearbeiten, damit Anfragen und Antworten zwischen Lambda und ASP.NET Core ordnungsgemäß übersetzt werden. Standardmäßig ist die Funktion für eine REST-API-Ereignisquelle konfiguriert. Für eine HTTP-API oder einen Application Load Balancer ersetzen Sie `(LambdaEventSource.RestApi)` durch eine der folgenden Optionen:
+ `(LambdaEventSource.HttpAPi)`
+ `(LambdaEventSource.ApplicationLoadBalancer)`

Um Ihre Minimal-API in Lambda bereitzustellen, führen Sie die folgenden Befehle aus, um in das Verzeichnis mit Ihrer Quellcodedatei zu navigieren und Ihre Funktion mit CloudFormation bereitzustellen.

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

# Arbeiten mit Ebenen für .NET-Lambda-Funktionen
<a name="dotnet-layers"></a>

Wir empfehlen nicht, [Ebenen](chapter-layers.md) zu verwenden, um Abhängigkeiten für in .NET geschriebene Lambda-Funktionen zu verwalten. Der Grund dafür ist, dass .NET eine kompilierte Sprache ist und Ihre Funktionen während der [Init](lambda-runtime-environment.md#runtimes-lifecycle-ib)-Phase trotzdem alle gemeinsam genutzten Assemblys manuell in den Speicher laden müssen, was die Kaltstartzeiten verlängern kann. Die Verwendung von Ebenen verkompliziert nicht nur den Bereitstellungsprozess, sondern verhindert auch, dass Sie die Vorteile der integrierten Compiler-Optimierungen nutzen können.

Um externe Abhängigkeiten mit Ihren .NET-Handlern zu verwenden, fügen Sie diese bei der Kompilierung direkt in Ihr Bereitstellungspaket ein. So vereinfachen Sie den Bereitstellungsprozess und können außerdem die integrierten .NET-Compiler-Optimierungen nutzen. Ein Beispiel dafür, wie Sie Abhängigkeiten wie NuGet-Pakete in Ihre Funktion importieren und verwenden können, finden Sie unter [Definieren des Lambda-Funktions-Handlers in C\$1](csharp-handler.md).

# Bereitstellen von .NET-Lambda-Funktionen mit Container-Images
<a name="csharp-image"></a>

Es gibt drei Möglichkeiten, ein Container-Image für eine .NET-Lambda-Funktion zu erstellen:
+ [Verwenden eines AWS Basis-Images für.NET](#csharp-image-instructions)

  Die [AWS -Basis-Images](images-create.md#runtimes-images-lp) sind mit einer Sprachlaufzeit, einem Laufzeitschnittstellen-Client zur Verwaltung der Interaktion zwischen Lambda und Ihrem Funktionscode und einem Laufzeitschnittstellen-Emulator für lokale Tests vorinstalliert.
+ [Es wird ein AWS reines Betriebssystem-Basis-Image verwendet](images-create.md#runtimes-images-provided)

  [AWS Basis-Images nur für Betriebssysteme](https://gallery.ecr.aws/lambda/provided) enthalten eine Amazon Linux-Distribution und den [Runtime-Interface-Emulator](https://github.com/aws/aws-lambda-runtime-interface-emulator/). Diese Images werden häufig verwendet, um Container-Images für kompilierte Sprachen wie [Go](go-image.md#go-image-provided) und [Rust](lambda-rust.md) sowie für eine Sprache oder Sprachversion zu erstellen, für die Lambda kein Basis-Image bereitstellt, wie Node.js 19. Sie können reine OS-Basis-Images auch verwenden, um eine [benutzerdefinierte Laufzeit](runtimes-custom.md) zu implementieren. Um das Image mit Lambda kompatibel zu machen, müssen Sie den [Laufzeitschnittstellen-Client für .NET](#csharp-image-clients) in das Image aufnehmen.
+ [Verwenden eines Nicht-Basis-Images AWS ](#csharp-image-clients)

  Sie können auch ein alternatives Basis-Image aus einer anderen Container-Registry verwenden. Sie können auch ein von Ihrer Organisation erstelltes benutzerdefiniertes Image verwenden. Um das Image mit Lambda kompatibel zu machen, müssen Sie den [Laufzeitschnittstellen-Client für .NET](#csharp-image-clients) in das Image aufnehmen.

**Tipp**  
Um die Zeit zu reduzieren, die benötigt wird, bis Lambda-Container-Funktionen aktiv werden, siehe die Docker-Dokumentation unter [Verwenden mehrstufiger Builds](https://docs.docker.com/build/building/multi-stage/). Um effiziente Container-Images zu erstellen, folgen Sie den [Bewährte Methoden für das Schreiben von Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/).

Auf dieser Seite wird erklärt, wie Sie Container-Images für Lambda erstellen, testen und bereitstellen.

**Topics**
+ [

## AWS Basis-Images für.NET
](#csharp-image-base)
+ [

## Verwenden eines AWS Basis-Images für.NET
](#csharp-image-instructions)
+ [

## Verwenden eines alternativen Basis-Images mit dem Laufzeitschnittstellen-Client
](#csharp-image-clients)

## AWS Basis-Images für.NET
<a name="csharp-image-base"></a>

AWS stellt die folgenden Basis-Images für.NET bereit:


| Tags (Markierungen) | Laufzeit | Betriebssystem | Dockerfile | Ablehnung | 
| --- | --- | --- | --- | --- | 
| 10 | .NET 10 | Amazon Linux 2023 | [Dockerfile für .NET 10 auf GitHub](https://github.com/aws/aws-lambda-base-images/blob/dotnet10/Dockerfile.dotnet10) |   14. November 2028   | 
| 9 | .NET 9 | Amazon Linux 2023 | [Dockerfile für .NET 9 auf GitHub](https://github.com/aws/aws-lambda-base-images/blob/dotnet9/Dockerfile.dotnet9) |   10. November 2026   | 
| 8 | .NET 8 | Amazon Linux 2023 | [Dockerfile für .NET 8 auf GitHub](https://github.com/aws/aws-lambda-base-images/blob/dotnet8/Dockerfile.dotnet8) |   10. November 2026   | 

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

## Verwenden eines AWS Basis-Images für.NET
<a name="csharp-image-instructions"></a>

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

Zur Durchführung der Schritte in diesem Abschnitt benötigen Sie Folgendes:
+ [.NET SDK](https://dotnet.microsoft.com/download) – Die folgenden Schritte verwenden das .NET 8-Basis-Image. Stellen Sie sicher, dass Ihre .NET-Version mit der Version des [Basis-Images](https://gallery.ecr.aws/lambda/dotnet) übereinstimmt, die Sie in Ihrer Docker-Datei angeben.
+ [Docker](https://docs.docker.com/get-docker) (Mindestversion 25.0.0)
+ Das Docker-[buildx-Plugin](https://github.com/docker/buildx/blob/master/README.md).

### Erstellen und Bereitstellen eines Images mithilfe eines Basis-Images
<a name="dotnet-image-create"></a>

In den folgenden Schritten verwenden Sie [Amazon.Lambda.Templates](https://github.com/aws/aws-lambda-dotnet#dotnet-cli-templates) und [Amazon.Lambda.Tools](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools), um ein.NET-Projekt zu erstellen. Anschließend erstellen Sie ein Docker-Image, laden das Image auf Amazon ECR hoch und stellen es auf einer Lambda-Funktion bereit.

1. Installieren Sie das [Amazon.Lambda.Templates-Paket.](https://github.com/aws/aws-lambda-dotnet#dotnet-cli-templates) NuGet 

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

1. Erstellen Sie ein .NET-Projekt mithilfe der `lambda.image.EmptyFunction`-Vorlage.

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

   Die Projektdateien werden im `MyFunction/src/MyFunction`-Verzeichnis gespeichert:
   + **aws-lambda-tools-defaults.json**: Gibt die Befehlszeilenoptionen für die Bereitstellung Ihrer Lambda-Funktion an.
   + **Function.cs**: Der Funktionscode Ihres Lambda-Handlers. Dies ist eine C\$1-Vorlage mit der `Amazon.Lambda.Core`-Standardbibliothek und einem `LambdaSerializer`-Standardattribut. Weitere Informationen über Serialisierungsanforderungen und -optionen finden Sie unter [Serialisierung in C\$1-Lambda-Funktionen](csharp-handler.md#csharp-handler-serializer). Sie können den bereitgestellten Code zum Testen verwenden oder ihn durch Ihren eigenen ersetzen.
   + **MyFunction.csproj**: Eine [.NET-Projektdatei](https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview#project-files), die die Dateien und Assemblys auflistet, aus denen Ihre Anwendung besteht.
   + **Dockerfile**: Sie können die bereitgestellte Docker-Datei zum Testen verwenden oder sie durch Ihre eigene ersetzen. Wenn Sie Ihre eigenen verwenden, stellen Sie sicher, dass Sie:
     + Setzen Sie die `FROM`-Eigenschaft auf den [URI des Basis-Images](https://gallery.ecr.aws/lambda/dotnet). Das Basis-Image und das `TargetFramework` in der Datei `MyFunction.csproj` müssen beide dieselbe .NET-Version verwenden. Um beispielsweise .NET 9 zu verwenden:
       + Docker-Datei: `FROM public.ecr.aws/lambda/dotnet:9`
       + MyFunction.csproj: `<TargetFramework>net9.0</TargetFramework>`
     + Legen Sie das `CMD`-Argument auf den Lambda-Funktionshandler fest. Das sollte mit dem `image-command` in `aws-lambda-tools-defaults.json` übereinstimmen.

1. Installieren Sie Amazon.Lambda.Tools [.NET Global Tool](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/).

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

   Wenn Amazon.Lambda.Tools bereits installiert ist, vergewissern Sie sich, dass Sie über die neueste Version verfügen.

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

1. Ändern Sie das Verzeichnis zu `MyFunction/src/MyFunction`, sofern Sie dies noch nicht getan haben.

   ```
   cd src/MyFunction
   ```

1. Verwenden Sie Amazon.Lambda.Tools, um das Docker-Image zu erstellen, es in ein neues Amazon-ECR-Repository zu verschieben und die Lambda-Funktion bereitzustellen.

   Für `--function-role` geben Sie den Rollennamen – nicht den Amazon-Ressourcenname (ARN) – der [Ausführungsrolle](lambda-intro-execution-role.md) für die Funktion an. Beispiel, `lambda-role`.

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

   Weitere Informationen zum Amazon.Lambda.Tools .NET Global Tool finden Sie im [AWS Extensions](https://github.com/aws/aws-extensions-for-dotnet-cli) for .NET CLI Repository unter. GitHub

1. Die Funktion aufrufen.

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

   Wenn alles erfolgreich ist, sehen Sie eine Antwort ähnlich der folgenden:

   ```
   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. Löschen Sie die Lambda-Funktion.

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

## Verwenden eines alternativen Basis-Images mit dem Laufzeitschnittstellen-Client
<a name="csharp-image-clients"></a>

Wenn Sie ein [OS-Basis-Image](images-create.md#runtimes-images-provided) oder ein alternatives Basis-Image verwenden, müssen Sie den Laufzeitschnittstellen-Client in das Image einbinden. Der Laufzeitschnittstellen-Client erweitert die [Laufzeit-API](runtimes-api.md), die die Interaktion zwischen Lambda und Ihrem Funktionscode verwaltet.

Das folgende Beispiel zeigt, wie Sie mithilfe eines AWS Nicht-Base-Images ein Container-Image für .NET erstellen und wie Sie das [Amazon.Lambda hinzufügen. RuntimeSupport ](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.RuntimeSupport/README.md#using-amazonlambdaruntimesupport-as-a-class-library)Paket, das der Lambda-Runtime-Interface-Client für .NET ist. Das Beispiel-Dockerfile verwendet das Basis-Image „Microsoft .NET 8“.

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

Zur Durchführung der Schritte in diesem Abschnitt benötigen Sie Folgendes:
+ [.NET SDK](https://dotnet.microsoft.com/download) — Für die folgenden Schritte wird ein .NET 9-Basisimage verwendet. Stellen Sie sicher, dass Ihre .NET-Version mit der Version des Basis-Images übereinstimmt, die Sie in Ihrer Docker-Datei angeben.
+ [Docker](https://docs.docker.com/get-docker) (Mindestversion 25.0.0)
+ Das Docker-[buildx-Plugin](https://github.com/docker/buildx/blob/master/README.md).

### Erstellen und Bereitstellen eines Images mithilfe eines alternativen Basis-Images
<a name="dotnet-alt-create"></a>

1. Installieren Sie das [Amazon.Lambda.Templates-Paket.](https://github.com/aws/aws-lambda-dotnet#dotnet-cli-templates) NuGet 

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

1. Erstellen Sie ein .NET-Projekt mithilfe der `lambda.CustomRuntimeFunction`-Vorlage. [Diese Vorlage enthält das 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)Paket.

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

1. Navigieren Sie zum `MyFunction/src/MyFunction` Verzeichnis . Hier werden die Projektdateien gespeichert. Prüfen Sie die folgenden Dateien:
   + **aws-lambda-tools-defaults.json** — In dieser Datei geben Sie die Befehlszeilenoptionen an, wenn Sie Ihre Lambda-Funktion bereitstellen.
   + **Function.cs** – Der Code enthält eine Klasse mit einer `Main`-Methode, die die Bibliothek `Amazon.Lambda.RuntimeSupport` als Bootstrap initialisiert. Die `Main`-Methode ist der Einstiegspunkt für den Prozess der Funktion. Die `Main`-Methode verpackt den Funktionshandler in einen Wrapper, mit dem der Bootstrap arbeiten kann. Weitere Informationen finden Sie unter Amazon.Lambda [verwenden. RuntimeSupport als Klassenbibliothek im Repository](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.RuntimeSupport/README.md#using-amazonlambdaruntimesupport-as-a-class-library). GitHub 
   + **MyFunction.csproj — [Eine.NET-Projektdatei](https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview#project-files)**, die die Dateien und Assemblys auflistet, aus denen Ihre Anwendung besteht.
   + **Readme.md** – Diese Datei enthält weitere Informationen zur Lambda-Beispielfunktion.

1. Öffnen Sie die Datei `aws-lambda-tools-defaults.json` und fügen Sie die folgenden Zeilen hinzu:

   ```
     "package-type": "image",
     "docker-host-build-output-dir": "./bin/Release/lambda-publish"
   ```
   + **package-type**: Definiert das Bereitstellungspaket als Container-Image.
   + **docker-host-build-output-dir**: Legt das Ausgabeverzeichnis für den Build-Prozess fest.  
**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. Erstellen Sie ein Dockerfile in Verzeichnis `MyFunction/src/MyFunction`. Das folgende Beispiel-Dockerfile verwendet ein Microsoft .NET-Basisimage anstelle eines [AWS -Basis-Images](#csharp-image-base).
   + Legen Sie `FROM`-Eigenschaft auf die Kennung des Basis-Images fest. Das Basis-Image und das `TargetFramework` in der Datei `MyFunction.csproj` müssen beide dieselbe .NET-Version verwenden.
   + Verwenden Sie den `COPY`-Befehl, um die Funktion in das Verzeichnis `/var/task` zu kopieren.
   + Legen Sie `ENTRYPOINT` auf das Modul fest, das der Docker-Container beim Start ausführen soll. In diesem Fall ist das Modul der Bootstrap, der die Bibliothek `Amazon.Lambda.RuntimeSupport` initialisiert.

   Beachten Sie, dass das Dockerfile-Beispiel keine [USER-Anweisung](https://docs.docker.com/reference/dockerfile/#user) enthält. Wenn Sie ein Container-Image für Lambda bereitstellen, definiert Lambda automatisch einen Standard-Linux-Benutzer mit Berechtigungen mit geringsten Rechten. Dies unterscheidet sich vom Standardverhalten von Docker, bei dem standardmäßig der `root`-Benutzer verwendet wird, wenn keine `USER`-Anweisung bereitgestellt wird.  
**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. Installieren Sie die Amazon.Lambda.Tools [.NET Global Tools-Erweiterung](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/).

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

   Wenn Amazon.Lambda.Tools bereits installiert ist, vergewissern Sie sich, dass Sie über die neueste Version verfügen.

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

1. Verwenden Sie Amazon.Lambda.Tools, um das Docker-Image zu erstellen, es in ein neues Amazon-ECR-Repository zu verschieben und die Lambda-Funktion bereitzustellen.

   Für `--function-role` geben Sie den Rollennamen – nicht den Amazon-Ressourcenname (ARN) – der [Ausführungsrolle](lambda-intro-execution-role.md) für die Funktion an. Beispiel, `lambda-role`.

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

   Weitere Informationen zur .NET-CLI-Erweiterung Amazon.Lambda.Tools finden Sie im [AWS Extensions](https://github.com/aws/aws-extensions-for-dotnet-cli) for .NET CLI-Repository unter. GitHub

1. Die Funktion aufrufen.

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

   Wenn alles erfolgreich ist, sehen Sie Folgendes:

   ```
   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. Löschen Sie die Lambda-Funktion.

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

# Kompilieren Sie.NET-Lambda-Funktionscode in ein natives Laufzeitformat
<a name="dotnet-native-aot"></a>

.NET 8 unterstützt die native Ahead-of-Time-Kompilierung (AOT). Mit nativem AOT können Sie Ihren Lambda-Funktionscode in ein natives Laufzeitformat kompilieren, wodurch die Notwendigkeit entfällt, .NET-Code zur Laufzeit zu kompilieren. Die native AOT-Kompilierung kann die Kaltstartzeit für Lambda-Funktionen reduzieren, die Sie in .NET schreiben. Weitere Informationen finden Sie unter [Introducing the .NET 8 runtime for AWS Lambda](https://aws.amazon.com/blogs/compute/introducing-the-net-8-runtime-for-aws-lambda/) im AWS-Compute-Blog.

**Topics**
+ [

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

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

## Erste Schritte
](#dotnet-native-aot-getting-started)
+ [

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

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

## Fehlerbehebung
](#dotnet-native-aot-troubleshooting)

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

Um eine Lambda-Funktion mit nativer AOT-Kompilierung zu erstellen, verwenden Sie die verwaltete .NET 8 Lambda-Laufzeit. Diese Laufzeit unterstützt die Verwendung sowohl der x86\$164- als auch arm64-Architektur.

Wenn Sie eine .NET Lambda-Funktion ohne AOT bereitstellen, wird Ihre Anwendung zunächst in IL-Code (Intermediate Language) kompiliert. Zur Laufzeit nimmt der Just-in-Time-Compiler (JIT) in der Lambda-Laufzeitumgebung den IL-Code und kompiliert ihn nach Bedarf in Maschinencode. Mit einer Lambda-Funktion, die im Voraus mit nativem AOT kompiliert wird, kompilieren Sie Ihren Code bei der Bereitstellung Ihrer Funktion in Maschinencode, sodass Sie nicht auf die .NET-Laufzeit oder das SDK in der Lambda-Laufzeit angewiesen sind, um Ihren Code vor der Ausführung zu kompilieren.

Eine Einschränkung von AOT ist, dass Ihr Anwendungscode in einer Umgebung mit demselben Amazon Linux 2023 (AL2023) Betriebssystem kompiliert werden muss, das auch die .NET 8-Laufzeitumgebung verwendet. Die .NET Lambda-CLI bietet Funktionen zum Kompilieren Ihrer Anwendung in einem Docker-Container mithilfe eines AL2023-Images.

Um mögliche Probleme mit der architekturübergreifenden Kompatibilität zu vermeiden, empfehlen wir dringend, dass Sie Ihren Code in einer Umgebung mit derselben Prozessorarchitektur kompilieren, die Sie für Ihre Funktion konfigurieren. Weitere Informationen zu den Einschränkungen der architekturübergreifenden Kompilierung finden Sie unter [Cross-Compilierung](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/cross-compile) in der Microsoft-.NET-Dokumentation.

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

**Docker**  
Um natives AOT zu verwenden, muss Ihr Funktionscode in einer Umgebung mit demselben AL2023-Betriebssystem wie die .NET 8-Laufzeit kompiliert werden. Die .NET-CLI-Befehle in den folgenden Abschnitten verwenden Docker, um Lambda-Funktionen in einer AL2023-Umgebung zu entwickeln und zu erstellen.

**.NET 8-SDK**  
Die native AOT-Kompilierung ist ein Feature von .NET 8. Sie müssen das [.NET 8-SDK](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) auf Ihrer Build-Machine installieren, nicht nur die Laufzeit.

**Amazon.Lambda.Tools**  
Verwenden Sie zum Erstellen Ihrer Lambda-Funktionen die [https://www.nuget.org/packages/Amazon.Lambda.Tools](https://www.nuget.org/packages/Amazon.Lambda.Tools)-[.NET Global Tools-Erweiterung](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/). Um Amazon.Lambda.Tools zu installieren, führen Sie den folgenden Befehl aus:  

```
dotnet tool install -g Amazon.Lambda.Tools
```
Weitere Informationen über die Amazon.Lambda.Tools .NET CLI-Erweiterung finden Sie im [AWS-Erweiterungen für .NET-CLI](https://github.com/aws/aws-extensions-for-dotnet-cli)-Repository auf GitHub.

**Amazon.Lambda.Templates**  
Verwenden Sie das [https://www.nuget.org/packages/Amazon.Lambda.Templates](https://www.nuget.org/packages/Amazon.Lambda.Templates)-NuGet-Paket, um Ihren Lambda-Funktionscode zu generieren. Zur Installation dieses Vorlagenpakets führen Sie den folgenden Befehl aus:  

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

## Erste Schritte
<a name="dotnet-native-aot-getting-started"></a>

Sowohl das.NET Global CLI als auch AWS Serverless Application Model (AWS SAM) bieten Vorlagen für erste Schritte zum Erstellen von Anwendungen mit nativem AOT. Um Ihre erste native AOT-Lambda-Funktion zu erstellen, führen Sie die Schritte in den folgenden Anweisungen aus.

**Um eine native AOT-kompilierte Lambda-Funktion zu initialisieren und bereitzustellen**

1. Initialisieren Sie ein neues Projekt unter Verwendung der nativen AOT-Vorlage und navigieren Sie dann in das Verzeichnis, das die erstellten `.cs`- und `.csproj`-Dateien enthält. In diesem Beispiel nennen wir unsere Funktion `NativeAotSample`.

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

   Die von der nativen AOT-Vorlage erstellte `Function.cs`-Datei enthält den folgenden Funktionscode.

   ```
   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
   ```

   Native AOT kompiliert Ihre Anwendung in eine einzige native Binärdatei. Der Einstiegspunkt dieser Binärdatei ist die `static Main`-Methode. Innerhalb von `static Main` wird die Lambda-Laufzeit gebootstrapped und die `FunctionHandler`-Methode eingerichtet. Als Teil des Runtime-Bootstrap wird ein quellgenerierter Serializer mit `new SourceGeneratorLambdaJsonSerializer<LambdaFunctionJsonSerializerContext>()` konfiguriert

1. Um Ihre Anwendung auf Lambda bereitzustellen, stellen Sie sicher, dass Docker in Ihrer lokalen Umgebung ausgeführt wird, und führen Sie den folgenden Befehl aus.

   ```
   dotnet lambda deploy-function
   ```

   Hinter den Kulissen lädt das .NET Global CLI ein AL2023-Docker-Image herunter und kompiliert Ihren Anwendungscode in einem laufenden Container. Die kompilierte Binärdatei wird zurück in Ihr lokales Dateisystem ausgegeben, bevor sie auf Lambda bereitgestellt wird.

1. Testen Sie Ihre Funktion, indem Sie den folgenden Befehl ausführen. Ersetzen Sie `<FUNCTION_NAME>` durch den Namen, den Sie für Ihre Funktion im Bereitstellungsassistenten gewählt haben.

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

   Die Antwort der CLI enthält Leistungsdetails für den Kaltstart (Initialisierungsdauer) und die Gesamtlaufzeit für Ihren Funktionsaufruf.

1. Führen Sie den folgenden Befehl aus, um die AWS-Ressourcen zu löschen, die Sie mit den vorherigen Schritten erstellt haben. Ersetzen Sie `<FUNCTION_NAME>` durch den Namen, den Sie für Ihre Funktion im Bereitstellungsassistenten gewählt haben. Durch das Löschen von AWS-Ressourcen, die Sie nicht mehr verwenden, können Sie verhindern, dass unnötige Gebühren Ihrem AWS-Konto-Konto in Rechnung gestellt werden.

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

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

Um Funktionen mithilfe von nativem AOT für Lambda bereitzustellen, muss Ihr Funktionscode die [quellgenerierte Serialisierung](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/source-generation-modes?pivots=dotnet-8-0) verwenden. Anstatt mithilfe der Laufzeitreflexion die Metadaten zu sammeln, die für den Zugriff auf Objekteigenschaften für die Serialisierung erforderlich sind, generieren Quellgeneratoren C\$1-Quelldateien, die beim Erstellen Ihrer Anwendung kompiliert werden. Um Ihren quellgenerierten Serializer korrekt zu konfigurieren, stellen Sie sicher, dass Sie alle Eingabe- und Ausgabeobjekte, die Ihre Funktion verwendet, sowie alle benutzerdefinierten Typen einbeziehen. Beispielsweise würde eine Lambda-Funktion, die Ereignisse von einer API-Gateway-REST-API empfängt und einen benutzerdefinierten `Product`-Typ zurückgibt, einen Serializer enthalten, der wie folgt definiert ist.

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

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

Natives AOT kürzt Ihren Anwendungscode als Teil der Kompilierung, um sicherzustellen, dass die Binärdatei so klein wie möglich ist. .NET 8 for Lambda bietet im Vergleich zu früheren Versionen von .NET eine verbesserte Trimmunterstützung. Support wurde zu den [Lambda-Laufzeitbibliotheken](https://github.com/aws/aws-lambda-dotnet/pull/1596), [AWS .NET SDK](https://github.com/aws/aws-sdk-net/pulls?q=is%3Apr+trimming), [.NET Lambda Annotations](https://github.com/aws/aws-lambda-dotnet/pull/1610) und .NET 8 selbst hinzugefügt.

Diese Verbesserungen bieten das Potenzial, Warnungen beim Trimmen während der Erstellung zu eliminieren, aber .NET wird niemals vollständig trimmsicher sein. Das bedeutet, dass Teile von Bibliotheken, auf die Ihre Funktion angewiesen ist, im Rahmen des Kompilierungsschritts entfernt werden können. Sie können dies verwalten, indem Sie `TrimmerRootAssemblies` als Teil Ihrer `.csproj`-Datei definieren, wie im folgenden Beispiel gezeigt. 

```
<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>
```

Beachten Sie, dass bei einer Trim-Warnung das Hinzufügen der Klasse, die die Warnung erzeugt, zu `TrimmerRootAssembly` das Problem möglicherweise nicht behebt. Eine Trim-Warnung weist darauf hin, dass die Klasse versucht, auf eine andere Klasse zuzugreifen, die erst zur Laufzeit ermittelt werden kann. Um Laufzeitfehler zu vermeiden, fügen Sie diese zweite Klasse zu `TrimmerRootAssembly` hinzu.

Weitere Informationen zur Verwaltung von Trimmwarnungen finden Sie in der Microsoft.NET-Dokumentation unter [Einführung in Trimmwarnungen](https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/fixing-warnings).

## Fehlerbehebung
<a name="dotnet-native-aot-troubleshooting"></a>

**Fehler: Betriebssystemübergreifende native Kompilierung wird nicht unterstützt.**  
Ihre Version des globalen Amazon.Lambda.Tools-.NET-Core-Tools ist veraltet. Aktualisieren Sie auf die neueste Version und versuchen Sie es erneut.

**Docker: das Image-Betriebssystem „Linux“ kann auf dieser Plattform nicht verwendet werden.**  
Docker ist auf Ihrem System für die Verwendung von Windows-Containern konfiguriert. Wechseln Sie zu Linux-Containern, um die native AOT-Entwicklungsumgebung auszuführen.

Weitere Informationen zu häufigen Fehlern finden Sie im [AWS NativeAOT für .NET](https://github.com/awslabs/dotnet-nativeaot-labs#common-errors)-Repository auf GitHub.

# Verwenden des Lambda-Kontextobjekts zum Abrufen von C\$1-Funktionsinformationen
<a name="csharp-context"></a>

Wenn Lambda Ihre Funktion ausführt, wird ein Context-Objekt an den [Handler](csharp-handler.md) übergeben. Dieses Objekt stellt Eigenschaften mit Informationen zum Aufruf, zur Funktion und zur Ausführungsumgebung bereit.

**Context-Eigenschaften**
+ `FunctionName` – Der Name der Lambda-Funktion.
+ `FunctionVersion` – Die [Version](configuration-versions.md) der Funktion.
+ `InvokedFunctionArn` – Der Amazon-Ressourcenname (ARN), der zum Aufrufen der Funktion verwendet wird. Gibt an, ob der Aufrufer eine Versionsnummer oder einen Alias angegeben hat.
+ `MemoryLimitInMB` – Die Menge an Arbeitsspeicher, die der Funktion zugewiesen ist.
+ `AwsRequestId` – Der Bezeichner der Aufrufanforderung.
+ `LogGroupName` – Protokollgruppe für die Funktion.
+ `LogStreamName` – Der Protokollstrom für die Funktionsinstance.
+ `RemainingTime` (`TimeSpan`) – Die Anzahl der Millisekunden, die vor der Zeitüberschreitung der Ausführung verbleiben.
+ `Identity` – Informationen zur Amazon-Cognito-Identität, die die Anforderung autorisiert hat.
+ `ClientContext` – (mobile Apps) Clientkontext, der Lambda von der Clientanwendung bereitgestellt wird.
+ `Logger` Das [Logger-Objekt](csharp-logging.md) für die Funktion.

Sie können die Informationen im `ILambdaContext`-Objekt verwenden, um zu Überwachungszwecken Informationen über den Aufruf Ihrer Funktion auszugeben. Der folgende Code enthält ein Beispiel dafür, wie Sie einem strukturierten Logging-Framework Kontextinformationen hinzufügen können. In diesem Beispiel fügt die Funktion `AwsRequestId` zu den Protokollausgaben hinzu. Die Funktion verwendet auch die `RemainingTime`-Eigenschaft, um eine Aufgabe während des Fluges abzubrechen, wenn die Zeitüberschreitung der Lambda-Funktion bald erreicht ist.

```
[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();
        }
    }
}
```

# C\$1-Lambda-Funktionen protokollieren und überwachen
<a name="csharp-logging"></a>

AWS Lambda überwacht automatisch Lambda-Funktionen und sendet Protokolleinträge an Amazon CloudWatch. Ihre Lambda-Funktion enthält eine CloudWatch Logs-Log-Gruppe und einen Log-Stream für jede Instanz Ihrer Funktion. Die Lambda-Laufzeitumgebung sendet Details zu den einzelnen Aufrufen an den Protokollstream und leitet Protokolle und andere Ausgaben aus dem Code Ihrer Funktion weiter. Weitere Informationen zu CloudWatch Logs finden Sie unter[Senden von Lambda-Funktionsprotokollen an CloudWatch Logs](monitoring-cloudwatchlogs.md).

**Topics**
+ [

## Erstellen einer Funktion, die Protokolle zurückgibt
](#csharp-logging-output)
+ [

## Verwenden von Lambda-Optionen für die erweiterte Protokollierung mit .NET
](#csharp-logging-advanced)
+ [

## Zusätzliche Protokollierungswerkzeuge und Bibliotheken
](#csharp-tools-libraries)
+ [

## Verwendung von Powertools für AWS Lambda (.NET) und für strukturiertes Logging AWS SAM
](#dotnet-logging-sam)
+ [

## Anzeigen von Protokollen in der Lambda-Konsole
](#csharp-logging-console)
+ [

## Protokolle in der CloudWatch Konsole anzeigen
](#csharp-logging-cwconsole)
+ [

## Logs mit dem Befehl () anzeigen AWS Command Line Interface AWS CLI
](#csharp-logging-cli)
+ [

## Löschen von Protokollen
](#csharp-logging-delete)

## Erstellen einer Funktion, die Protokolle zurückgibt
<a name="csharp-logging-output"></a>

Um Logs aus Ihrem Funktionscode auszugeben, können Sie den [ILambdaLogger](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.Core/ILambdaLogger.cs) für das Kontextobjekt, die Methoden der [Console-Klasse](https://docs.microsoft.com/en-us/dotnet/api/system.console) oder eine beliebige Logging-Bibliothek verwenden, die in `stdout` oder schreibt`stderr`.

Die .NET-Laufzeit protokolliert die Zeilen `START`, `END` und `REPORT` für jeden Aufruf. Die Berichtszeile enthält die folgenden Details.

**Datenfelder für REPORT-Zeilen**
+ **RequestId**— Die eindeutige Anforderungs-ID für den Aufruf.
+ **Dauer** – Die Zeit, die die Handler-Methode Ihrer Funktion mit der Verarbeitung des Ereignisses verbracht hat.
+ **Fakturierte Dauer** – Die für den Aufruf fakturierte Zeit.
+ **Speichergröße** – Die der Funktion zugewiesene Speichermenge.
+ **Max. verwendeter Speicher** – Die Speichermenge, die von der Funktion verwendet wird. Wenn Aufrufe eine Ausführungsumgebung gemeinsam nutzen, meldet Lambda den maximalen Speicherverbrauch für alle Aufrufe. Dieses Verhalten kann zu einem höheren als erwarteten gemeldeten Wert führen.
+ **Initialisierungsdauer** – Für die erste Anfrage die Zeit, die zur Laufzeit zum Laden der Funktion und Ausführen von Code außerhalb der Handler-Methode benötigt wurde.
+ **XRAY TraceId** [— Für verfolgte Anfragen die AWS X-Ray Trace-ID.](services-xray.md)
+ **SegmentId**— Für verfolgte Anfragen die X-Ray-Segment-ID.
+ **Stichprobe** – Bei verfolgten Anforderungen das Stichprobenergebnis.

## Verwenden von Lambda-Optionen für die erweiterte Protokollierung mit .NET
<a name="csharp-logging-advanced"></a>

Um Ihnen mehr Kontrolle darüber zu geben, wie die Protokolle Ihrer Funktionen erfasst, verarbeitet und verwendet werden, können Sie die folgenden Protokollierungsoptionen für unterstützte .NET-Laufzeiten konfigurieren:
+ **Protokollformat** – Wählen Sie zwischen Klartext und einem strukturierten JSON-Format für die Protokolle Ihrer Funktion aus.
+ **Protokollebene** — für Logs im JSON-Format wählen Sie die Detailebene der Logs, an die Lambda sendet CloudWatch, wie ERROR, DEBUG oder INFO
+ **Protokollgruppe** — wählen Sie die CloudWatch Protokollgruppe aus, an die Ihre Funktion Logs sendet

Weitere Informationen zu diesen Protokollierungsoptionen und Anweisungen zur Konfiguration Ihrer Funktion für deren Verwendung finden Sie unter [Konfigurieren erweiterter Protokollierungsoptionen für Lambda-Funktionen](monitoring-logs.md#monitoring-cloudwatchlogs-advanced).

Informationen zur Verwendung der Optionen für das Protokollformat und die Protokollebene mit Ihren .NET-Lambda-Funktionen finden Sie in den folgenden Abschnitten.

### Verwenden des strukturierten JSON-Protokollformats mit .NET
<a name="csharp-logging-advanced-JSON"></a>

Wenn Sie JSON für das Protokollformat Ihrer Funktion auswählen, sendet Lambda die Protokollausgabe mithilfe von [ILambdaLogger](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.Core/ILambdaLogger.cs) als strukturiertes JSON. Jedes JSON-Protokollobjekt enthält mindestens fünf Schlüssel-Wert-Paare mit den folgenden Schlüsseln:
+ `"timestamp"` – die Uhrzeit, zu der die Protokollmeldung generiert wurde
+ `"level"` – die der Meldung zugewiesene Protokollebene
+ `"requestId"` – die eindeutige Anforderungs-ID für den Funktionsaufruf
+ `"traceId"` – Die Umgebungsvariable `_X_AMZN_TRACE_ID`
+ `"message"` – der Inhalt der Protokollmeldung

Die `ILambdaLogger`-Instance kann zusätzliche Schlüssel-Wert-Paare hinzufügen, beispielsweise beim Protokollieren von Ausnahmen. Sie können auch Ihre eigenen zusätzlichen Parameter angeben, wie im Abschnitt [Vom Kunden bereitgestellte Protokollparameter](#csharp-logging-advanced-JSON-user-supplied) beschrieben.

**Anmerkung**  
Wenn Ihr Code bereits eine andere Protokollierungsbibliothek verwendet, um JSON-formatierte Protokolle zu erstellen, stellen Sie sicher, dass das Protokollformat Ihrer Funktion auf Klartext gesetzt ist. Wenn Sie das Protokollformat auf JSON setzen, werden Ihre Protokollausgaben doppelt codiert.

Der folgende Beispiel-Logging-Befehl zeigt, wie Sie eine Protokollnachricht mit dem Level `INFO` schreiben.

**Example .NET-Protokollierungscode**  

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

Sie können auch eine generische Protokollebene verwenden, die die Protokollebene als Argument verwendet, wie im folgenden Beispiel gezeigt.

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

Die Protokollausgabe dieser Beispielcodefragmente würde wie folgt in CloudWatch Logs erfasst:

**Example JSON-Protokolldatensatz**  

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

**Anmerkung**  
Wenn Sie das Protokollformat Ihrer Funktion so konfigurieren, dass statt JSON reiner Text verwendet wird, entspricht die in der Meldung erfasste Protokollstufe der Microsoft-Konvention, die eine vierstellige Bezeichnung vorsieht. Die Protokollebene von `Debug` wird in der Nachricht beispielsweise als `dbug` dargestellt.  
Wenn Sie Ihre Funktion für die Verwendung von Protokollen im JSON-Format konfigurieren, verwendet die im Protokoll erfasste Protokollebene die vollständige Bezeichnung, wie im Beispiel für den JSON-Protokolldatensatz gezeigt.

Wenn Sie Ihrer Protokollausgabe keine Ebene zuweisen, weist Lambda ihr automatisch die Ebene INFO zu.

#### Protokollierungsausnahmen in JSON
<a name="csharp-logging-advanced-JSON-exceptions"></a>

Wenn Sie die strukturierte JSON-Protokollierung mit `ILambdaLogger` verwenden, können Sie Ausnahmen in Ihrem Code protokollieren, wie im folgenden Beispiel gezeigt.

**Example Verwendung der Ausnahmeprotokollierung**  

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

Das von diesem Code ausgegebene Protokollformat wird im folgenden JSON-Beispiel gezeigt. Beachten Sie, dass die `message`-Eigenschaft im JSON mithilfe des im `LogWarning`-Aufruf angegebenen Nachrichtenarguments aufgefüllt wird, während die `errorMessage`-Eigenschaft aus der `Message`-Eigenschaft der Ausnahme selbst stammt.

**Example JSON-Protokolldatensatz**  

```
{
    "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>"]
}
```

Wenn das Protokollierungsformat Ihrer Funktion auf JSON gesetzt ist, gibt Lambda auch Protokollnachrichten im JSON-Format aus, wenn Ihr Code eine nicht abgefangene Ausnahme auslöst. Der folgende Beispielcodeausschnitt und die Protokollnachricht zeigen, wie nicht abgefangene Ausnahmen protokolliert werden.

**Example Ausnahmecode**  

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

**Example JSON-Protokolldatensatz**  

```
{
    "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>"]
}
```

#### Vom Kunden bereitgestellte Protokollparameter
<a name="csharp-logging-advanced-JSON-user-supplied"></a>

Bei JSON-formatierten Protokollmeldungen können Sie zusätzliche Protokollparameter angeben und diese in das Protokoll `message` aufnehmen. Der folgende Codeausschnitt zeigt einen Befehl zum Hinzufügen von zwei vom Benutzer angegebenen Parametern mit der Bezeichnung `retryAttempt` und `uri`. Im Beispiel stammt der Wert dieser Parameter aus den Argumenten `retryAttempt` und `uriDestination`, die an den Protokollierungsbefehl übergeben wurden.

**Example JSON-Protokollierungsbefehl mit zusätzlichen Parametern**  

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

Die von diesem Befehl ausgegebene Protokollmeldung ist im folgenden JSON-Beispiel dargestellt.

**Example JSON-Protokolldatensatz**  

```
{
    "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/"
}
```

**Tipp**  
Sie können bei der Angabe zusätzlicher Parameter auch Positionseigenschaften anstelle von Namen verwenden. Beispielsweise könnte der Protokollierungsbefehl im vorherigen Beispiel auch wie folgt geschrieben werden:  

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

Beachten Sie, dass Lambda bei der Angabe zusätzlicher Protokollierungsparameter diese als Top-Level-Eigenschaften im JSON-Protokollsatz erfasst. Dieser Ansatz unterscheidet sich von einigen gängigen .NET-Protokollierungsbibliotheken, wie z. B. `Serilog`, die zusätzliche Parameter in einem separaten untergeordneten Objekt erfassen.

Wenn das Argument, das Sie für einen zusätzlichen Parameter angeben, ein komplexes Objekt ist, verwendet Lambda standardmäßig die `ToString()`-Methode, um den Wert bereitzustellen. Um anzugeben, dass ein Argument JSON-serialisiert werden soll, verwenden Sie das Präfix `@`, wie im folgenden Codeschnipsel gezeigt. In diesem Beispiel ist `User` ein Objekt mit den Eigenschaften `FirstName` und `LastName`.

**Example JSON-Protokollierungsbefehl mit serialisiertem JSON-Objekt**  

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

Die von diesem Befehl ausgegebene Protokollmeldung ist im folgenden JSON-Beispiel dargestellt.

**Example JSON-Protokolldatensatz**  

```
{
    "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"
    }
}
```

Wenn das Argument für einen zusätzlichen Parameter ein Array ist oder `IList` oder `IDictionary` implementiert, fügt Lambda das Argument der JSON-Protokollnachricht als Array hinzu, wie im folgenden Beispiel-JSON-Protokollsatz gezeigt. In diesem Beispiel nimmt `{users}` ein `IList`-Argument entgegen, das Instanzen der `User`-Eigenschaft mit demselben Format wie im vorherigen Beispiel enthält. Lambda wandelt dieses `IList` in ein Array um, wobei jeder Wert mit der `ToString`-Methode erstellt wird.

**Example JSON-Protokolldatensatz mit einem `IList`-Argument**  

```
{
    "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"       
    ] 
}
```

Sie können die Liste auch mit JSON serialisieren, indem Sie das `@`-Präfix in Ihrem Protokollierungsbefehl verwenden. Im folgenden JSON-Protokolldatensatz ist die Eigenschaft `users` in JSON serialisiert.

**Example JSON-Protokolldatensatz mit einem serialisierten JSON-Argument `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": 
    [
        {
            "FirstName": "Alejandro",
            "LastName": "Rosalez"
        },
        {
            "FirstName": "John",
            "LastName": "Stiles"
        }        
    ] 
}
```

### Verwenden der Filterung auf Protokollebene mit .NET
<a name="csharp-logging-advanced-levels"></a>

Durch die Konfiguration der Filterung auf Protokollebene können Sie festlegen, dass nur Protokolle mit einer bestimmten Detailebene oder niedriger an Logs gesendet werden. CloudWatch Informationen zur Konfiguration der Filterung auf Protokollebene für Ihre Funktion finden Sie unter [Filterung auf Protokollebene](monitoring-cloudwatchlogs-log-level.md).

 AWS Lambda Um Ihre Protokollnachrichten nach Protokollebene zu filtern, können Sie entweder Protokolle im JSON-Format oder die `Console` .NET-Methoden zur Ausgabe von Protokollnachrichten verwenden. Um Protokolle im JSON-Format zu erstellen, [konfigurieren Sie den Protokolltyp Ihrer Funktion auf JSON](monitoring-cloudwatchlogs-logformat.md#monitoring-cloudwatchlogs-set-format) und verwenden Sie die `ILambdaLogger`-Instance.

Bei JSON-formatierten Protokollen filtert Lambda Ihre Protokollausgaben anhand des Schlüssel-Wert-Paares „level“ im JSON-Objekt, das in [Verwenden des strukturierten JSON-Protokollformats mit .NET](#csharp-logging-advanced-JSON) beschrieben wird.

Wenn Sie die `Console` .NET-Methoden verwenden, um Nachrichten in CloudWatch Logs zu schreiben, wendet Lambda Log-Levels wie folgt auf Ihre Nachrichten an:
+ **Konsole. WriteLine **method - Lambda wendet ein Log-Level von `INFO`
+ **Console.Error-Methode** – Lambda wendet eine Protokollebene von `ERROR` an

Wenn Sie Ihre Funktion so konfigurieren, dass sie Filterung auf Protokollebene verwendet, müssen Sie aus den folgenden Optionen für die Protokollebene auswählen, die Lambda an Logs senden soll. CloudWatch Beachten Sie die Zuordnung der von Lambda verwendeten Protokollebenen zu den Microsoft-Standardstufen, die von .NET `ILambdaLogger` verwendet werden.


| Lambda-Protokollebene | Äquivalente Microsoft-Ebene | Standardnutzung | 
| --- | --- | --- | 
| TRACE (am detailliertesten) | Trace | Die detailliertesten Informationen, die verwendet werden, um den Ausführungspfad Ihres Codes nachzuverfolgen | 
| DEBUG | Debuggen | Detaillierte Informationen für das System-Debugging | 
| INFO | Informationen | Meldungen, die den normalen Betrieb Ihrer Funktion erfassen | 
| WARN | Warnung | Meldungen über mögliche Fehler, die zu unerwartetem Verhalten führen können, wenn sie nicht behoben werden | 
| ERROR | Fehler | Meldungen über Probleme, die verhindern, dass der Code wie erwartet funktioniert | 
| FATAL (am wenigsten Details) | Kritisch | Meldungen über schwerwiegende Fehler, die dazu führen, dass die Anwendung nicht mehr funktioniert | 

Lambda sendet Protokolle mit der ausgewählten Detailebene und niedriger bis CloudWatch. Wenn Sie beispielsweise die Protokollebene WARN konfigurieren, sendet Lambda Protokolle, die den Stufen WARN, ERROR und FATAL entsprechen.

## Zusätzliche Protokollierungswerkzeuge und Bibliotheken
<a name="csharp-tools-libraries"></a>

[Powertools for AWS Lambda (.NET)](https://docs.aws.amazon.com/powertools/dotnet/) ist ein Entwickler-Toolkit zur Implementierung von Best Practices für Serverless und zur Steigerung der Entwicklergeschwindigkeit. Das [Logging-Serviceprogramm](https://docs.aws.amazon.com/powertools/dotnet/core/logging/) bietet einen für Lambda optimierten Logger, der zusätzliche Informationen zum Funktionskontext all Ihrer Funktionen enthält, wobei die Ausgabe als JSON strukturiert ist. Mit diesem Serviceprogramm können Sie Folgendes tun:
+ Erfassung von Schlüsselfeldern aus dem Lambda-Kontext, Kaltstart und Strukturen der Protokollierungsausgabe als JSON
+ Protokollieren Sie Ereignisse von Lambda-Aufrufen, wenn Sie dazu aufgefordert werden (standardmäßig deaktiviert)
+ Alle Protokolle nur für einen bestimmten Prozentsatz der Aufrufe über Protokollstichproben drucken (standardmäßig deaktiviert)
+ Fügen Sie dem strukturierten Protokoll zu einem beliebigen Zeitpunkt zusätzliche Schlüssel hinzu
+ Verwenden Sie einen benutzerdefinierten Protokollformatierer (Bring Your Own Formatter), um Protokolle in einer Struktur auszugeben, die mit dem Logging RFC Ihres Unternehmens kompatibel ist

## Verwendung von Powertools für AWS Lambda (.NET) und für strukturiertes Logging AWS SAM
<a name="dotnet-logging-sam"></a>

Gehen Sie wie folgt vor, um eine Hello World C\$1-Beispielanwendung mit integrierten [Powertools for AWS Lambda (.NET)](https://docs.powertools.aws.dev/lambda-dotnet) -Modulen herunterzuladen, zu erstellen und bereitzustellen. Verwenden Sie dazu die. AWS SAM Diese Anwendung implementiert ein grundlegendes API-Backend und verwendet Powertools zum Ausgeben von Protokollen, Metriken und Traces. Es besteht aus einem Amazon-API-Gateway-Endpunkt und einer Lambda-Funktion. Wenn Sie eine GET-Anfrage an den API-Gateway-Endpunkt senden, ruft die Lambda-Funktion Logs und Metriken auf, sendet sie im Embedded Metric Format an CloudWatch und sendet Traces an. AWS X-Ray Die Funktion gibt eine `hello world`-Nachricht zurück.

**Voraussetzungen**

Zur Durchführung der Schritte in diesem Abschnitt benötigen Sie Folgendes:
+ .NET 8
+ [AWS CLI Version 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS SAM CLI Version 1.75 oder höher](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html). Wenn Sie eine ältere Version der AWS SAM CLI haben, finden Sie weitere Informationen unter [Upgrade der AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade).

**Stellen Sie eine AWS SAM Beispielanwendung bereit**

1. Initialisieren Sie die Anwendung mithilfe der Hello TypeScript World-Vorlage.

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

1. Entwickeln Sie die App.

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

1. Stellen Sie die Anwendung bereit.

   ```
   sam deploy --guided
   ```

1. Folgen Sie den Anweisungen auf dem Bildschirm. Um die im interaktiven Erlebnis bereitgestellten Standardoptionen zu akzeptieren, drücken Sie `Enter`.
**Anmerkung**  
Für ist **HelloWorldFunction möglicherweise keine Autorisierung definiert. Ist das in Ordnung?** , stellen Sie sicher, dass Sie eintreten`y`.

1. Rufen Sie die URL der bereitgestellten Anwendung ab:

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

1. Rufen Sie den API-Endpunkt auf:

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

   Wenn der Link erfolgreich ausgeführt wurde, sehen Sie die folgende Antwort:

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

1. Führen Sie [sam logs](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-logs.html) aus, um die Protokolle für die Funktion abzurufen. Weitere Informationen finden Sie unter [Arbeiten mit Protokollen](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-logging.html) im *AWS Serverless Application Model -Entwicklerhandbuch*.

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

   Das Ergebnis sieht folgendermaßen aus:

   ```
   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. Dies ist ein öffentlicher API-Endpunkt, der über das Internet zugänglich ist. Es wird empfohlen, dass Sie den Endpunkt nach dem Testen löschen.

   ```
   sam delete
   ```

### Verwalten der Protokollaufbewahrung
<a name="csharp-log-retention"></a>

Wenn Sie eine Funktion löschen, werden Protokollgruppen nicht automatisch gelöscht. Um zu vermeiden, dass Protokolle auf unbestimmte Zeit gespeichert werden, löschen Sie die Protokollgruppe oder konfigurieren Sie einen Aufbewahrungszeitraum, nach dessen Ablauf die Protokolle CloudWatch automatisch gelöscht werden. Um die Aufbewahrung von Protokollen einzurichten, fügen Sie Ihrer AWS SAM Vorlage Folgendes hinzu:

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

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

## Anzeigen von Protokollen in der Lambda-Konsole
<a name="csharp-logging-console"></a>

Sie können die Lambda-Konsole verwenden, um die Protokollausgabe nach dem Aufrufen einer Lambda-Funktion anzuzeigen.

Wenn Ihr Code über den eingebetteten **Code**-Editor getestet werden kann, finden Sie Protokolle in den **Ausführungsergebnissen**. Wenn Sie das Feature Konsolentest verwenden, um eine Funktion aufzurufen, finden Sie die **Protokollausgabe** im Abschnitt **Details**.

## Protokolle in der CloudWatch Konsole anzeigen
<a name="csharp-logging-cwconsole"></a>

Sie können die CloudWatch Amazon-Konsole verwenden, um Protokolle für alle Lambda-Funktionsaufrufe anzuzeigen.

**Um Protokolle auf der Konsole anzuzeigen CloudWatch**

1. Öffnen Sie die [Seite Protokollgruppen](https://console.aws.amazon.com/cloudwatch/home?#logs:) auf der CloudWatch Konsole.

1. Wählen Sie die Protokollgruppe für Ihre Funktion (***your-function-name*/aws/lambda/**).

1. Wählen Sie eine Protokollstream aus.

Jeder Protokoll-Stream entspricht einer [Instance Ihrer Funktion](lambda-runtime-environment.md). Ein Protokollstream wird angezeigt, wenn Sie Ihre Lambda-Funktion aktualisieren und wenn zusätzliche Instanzen für gleichzeitige Aufrufe erstellt werden. Um Logs für einen bestimmten Aufruf zu finden, empfehlen wir, Ihre Funktion mit zu instrumentieren. AWS X-Ray X-Ray erfasst Details zu der Anforderung und dem Protokollstream in der Trace.

## Logs mit dem Befehl () anzeigen AWS Command Line Interface AWS CLI
<a name="csharp-logging-cli"></a>

Das AWS CLI ist ein Open-Source-Tool, mit dem Sie mithilfe von Befehlen in Ihrer Befehlszeilen-Shell mit AWS Diensten interagieren können. Zur Durchführung der Schritte in diesem Abschnitt benötigen Sie [AWS CLI Version 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).

Sie können die [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) verwenden, um Protokolle für einen Aufruf mit der `--log-type`-Befehlsoption abzurufen. Die Antwort enthält das Feld `LogResult`, das bis zu 4 KB base64-verschlüsselte Protokolle aus dem Aufruf enthält.

**Example eine Log-ID abrufen**  
Das folgende Beispiel zeigt, wie eine *Protokoll-ID* aus dem `LogResult`-Feld für eine Funktion namens `my-function` abgerufen wird.  

```
aws lambda invoke --function-name my-function out --log-type Tail
```
Die Ausgabe sollte folgendermaßen aussehen:  

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

**Example entschlüsseln der Protokolle**  
Verwenden Sie in derselben Eingabeaufforderung das `base64`-Dienstprogramm, um die Protokolle zu entschlüsseln. Das folgende Beispiel zeigt, wie Base64-codierte Logs für abgerufen werde `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
```
Die **cli-binary-format** Option ist erforderlich, wenn Sie AWS CLI Version 2 verwenden. Um dies zur Standardeinstellung zu machen, führen Sie `aws configure set cli-binary-format raw-in-base64-out` aus. Weitere Informationen finden Sie unter [Von AWS CLI unterstützte globale Befehlszeilenoptionen](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) im *AWS Command Line Interface -Benutzerhandbuch für Version 2*.  
Die Ausgabe sollte folgendermaßen aussehen:  

```
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
```
Das `base64`-Dienstprogramm ist unter Linux, macOS und [Ubuntu auf Windows](https://docs.microsoft.com/en-us/windows/wsl/install-win10)verfügbar. macOS-Benutzer müssen möglicherweise `base64 -D` verwenden.

**Example get-logs.sh-Skript**  
Verwenden Sie in derselben Eingabeaufforderung das folgende Skript, um die letzten fünf Protokollereignisse herunterzuladen. Das Skript verwendet `sed` zum Entfernen von Anführungszeichen aus der Ausgabedatei und wechselt 15 Sekunden lang in den Ruhezustand, um Zeit einzuräumen, damit Protokolle verfügbar werden können. Die Ausgabe enthält die Antwort von Lambda und die `get-log-events`Ausgabe des Befehls.   
Kopieren Sie den Inhalt des folgenden Codebeispiels und speichern Sie es in Ihrem Lambda-Projektverzeichnis unter `get-logs.sh`.  
Die **cli-binary-format** Option ist erforderlich, wenn Sie AWS CLI Version 2 verwenden. Um dies zur Standardeinstellung zu machen, führen Sie `aws configure set cli-binary-format raw-in-base64-out` aus. Weitere Informationen finden Sie unter [Von AWS CLI unterstützte globale Befehlszeilenoptionen](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) im *AWS Command Line Interface -Benutzerhandbuch für Version 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 macOS und Linux (nur diese Systeme)**  
In derselben Eingabeaufforderung müssen macOS- und Linux-Benutzer möglicherweise den folgenden Befehl ausführen, um sicherzustellen, dass das Skript ausführbar ist.  

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

**Example die letzten fünf Protokollereignisse abrufen**  
Führen Sie an derselben Eingabeaufforderung das folgende Skript aus, um die letzten fünf Protokollereignisse abzurufen.  

```
./get-logs.sh
```
Die Ausgabe sollte folgendermaßen aussehen:  

```
{
    "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"
}
```

## Löschen von Protokollen
<a name="csharp-logging-delete"></a>

Wenn Sie eine Funktion löschen, werden Protokollgruppen nicht automatisch gelöscht. Um das unbegrenzte Speichern von Protokollen zu vermeiden, löschen Sie die Protokollgruppe oder [konfigurieren Sie eine Aufbewahrungszeitraum](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#SettingLogRetention) nach dem Protokolle automatisch gelöscht werden.

# Instrumentierung von C\$1-Code in AWS Lambda
<a name="csharp-tracing"></a>

Lambda lässt sich integrieren AWS X-Ray , um Ihnen zu helfen, Lambda-Anwendungen zu verfolgen, zu debuggen und zu optimieren. Sie können mit X-Ray eine Anforderung verfolgen, während sie Ressourcen in Ihrer Anwendung durchläuft, die Lambda-Funktionen und andere AWS -Services enthalten können.

Um Protokollierungsdaten an X-Ray zu senden, können Sie eine von drei SDK-Bibliotheken verwenden:
+ [AWS Distro for OpenTelemetry (ADOT)](https://aws.amazon.com/otel) — Eine sichere, produktionsbereite und AWS unterstützte Distribution des () SDK. OpenTelemetry OTel
+ [AWS X-Ray SDK für .NET](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-dotnet.html) – Ein SDK zum Generieren und Senden von Nachverfolgungsdaten an X-Ray.
+ [Powertools for AWS Lambda (.NET)](https://docs.aws.amazon.com/powertools/dotnet/) — Ein Entwickler-Toolkit zur Implementierung von Best Practices für Serverless und zur Steigerung der Entwicklergeschwindigkeit.

Jedes SDKs bietet Möglichkeiten, Ihre Telemetriedaten an den X-Ray-Dienst zu senden. Sie können dann mit X-Ray die Leistungsmetriken Ihrer Anwendung anzeigen, filtern und erhalten, um Probleme und Möglichkeiten zur Optimierung zu identifizieren.

**Wichtig**  
X-Ray und Powertools für AWS Lambda SDKs sind Teil einer eng integrierten Instrumentierungslösung, die von AWS angeboten wird. Die ADOT Lambda Layers sind Teil eines branchenweiten Standards für die Verfolgung von Instrumenten, die im Allgemeinen mehr Daten erfassen, aber möglicherweise nicht für alle Anwendungsfälle geeignet sind. Sie können die end-to-end Ablaufverfolgung in X-Ray mit beiden Lösungen implementieren. Weitere Informationen zur Auswahl zwischen beiden finden Sie unter [Wählen zwischen der AWS Distribution für Open Telemetry und](https://docs.aws.amazon.com/xray/latest/devguide/xray-instrumenting-your-app.html#xray-instrumenting-choosing) X-Ray. SDKs

**Topics**
+ [

## Verwendung von Powertools für AWS Lambda (.NET) und für die Nachverfolgung AWS SAM
](#dotnet-tracing-sam)
+ [

## Instrumentierung Ihrer .NET-Funktionen mithilfe von X-Ray-SDK
](#dotnet-xray-sdk)
+ [

## Aktivieren der Nachverfolgung mit der Lambda-Konsole
](#dotnet-tracing-console)
+ [

## Aktivieren der Nachverfolgung mit der Lambda-API
](#dotnet-tracing-api)
+ [

## Die Ablaufverfolgung wird aktiviert mit CloudFormation
](#dotnet-tracing-cloudformation)
+ [

## Interpretieren einer X-Ray-Nachverfolgung
](#dotnet-tracing-interpretation)

## Verwendung von Powertools für AWS Lambda (.NET) und für die Nachverfolgung AWS SAM
<a name="dotnet-tracing-sam"></a>

Gehen Sie wie folgt vor, um eine Hello World C\$1-Beispielanwendung mit integrierten [Powertools for AWS Lambda (.NET)](https://docs.powertools.aws.dev/lambda-dotnet) -Modulen herunterzuladen, zu erstellen und bereitzustellen. Verwenden Sie dazu die. AWS SAM Diese Anwendung implementiert ein grundlegendes API-Backend und verwendet Powertools zum Ausgeben von Protokollen, Metriken und Traces. Es besteht aus einem Amazon-API-Gateway-Endpunkt und einer Lambda-Funktion. Wenn Sie eine GET-Anfrage an den API-Gateway-Endpunkt senden, ruft die Lambda-Funktion Logs und Metriken auf, sendet sie im Embedded Metric Format an CloudWatch und sendet Traces an. AWS X-Ray Die Funktion gibt eine Hello-World-Nachricht zurück.

**Voraussetzungen**

Zur Durchführung der Schritte in diesem Abschnitt benötigen Sie Folgendes:
+ .NET 8
+ [AWS CLI Version 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS SAM CLI Version 1.75 oder höher](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html). Wenn Sie eine ältere Version der AWS SAM CLI haben, finden Sie weitere Informationen unter [Upgrade der AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade).

**Stellen Sie eine AWS SAM Beispielanwendung bereit**

1. Initialisieren Sie die Anwendung mithilfe der Hello TypeScript World-Vorlage.

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

1. Entwickeln Sie die App.

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

1. Stellen Sie die Anwendung bereit.

   ```
   sam deploy --guided
   ```

1. Folgen Sie den Anweisungen auf dem Bildschirm. Um die im interaktiven Erlebnis bereitgestellten Standardoptionen zu akzeptieren, drücken Sie `Enter`.
**Anmerkung**  
Für ist **HelloWorldFunction möglicherweise keine Autorisierung definiert. Ist das in Ordnung?** , stellen Sie sicher, dass Sie eintreten`y`.

1. Rufen Sie die URL der bereitgestellten Anwendung ab:

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

1. Rufen Sie den API-Endpunkt auf:

   ```
   curl <URL_FROM_PREVIOUS_STEP>
   ```

   Wenn der Link erfolgreich ausgeführt wurde, sehen Sie die folgende Antwort:

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

1. Führen Sie [sam traces](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-traces.html) aus, um die Traces für die Funktion zu erhalten.

   ```
   sam traces
   ```

   Das Nachverfolgungsergebnis sieht folgendermaßen aus:

   ```
   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. Dies ist ein öffentlicher API-Endpunkt, der über das Internet zugänglich ist. Es wird empfohlen, dass Sie den Endpunkt nach dem Testen löschen.

   ```
   sam delete
   ```

X-Ray verfolgt nicht alle Anfragen an Ihre Anwendung nach. X-Ray wendet einen Sampling-Algorithmus an, um sicherzustellen, dass die Nachverfolgung effizient ist, und stellt dennoch ein repräsentatives Beispiel aller Anfragen bereit. Die Samplingrate beträgt 1 Anforderung pro Sekunde und 5 Prozent aller weiteren Anforderungen. Sie können die X-Ray-Samplingrate nicht für Ihre Funktionen konfigurieren.

## Instrumentierung Ihrer .NET-Funktionen mithilfe von X-Ray-SDK
<a name="dotnet-xray-sdk"></a>

Sie können Ihren Funktionscode instrumentieren, um Metadaten aufzuzeichnen und Downstream-Aufrufe zu verfolgen. Um Details zu Aufrufen aufzuzeichnen, die Ihre Funktion an andere Ressourcen und Dienste vornimmt, verwenden Sie das AWS X-Ray SDK für .NET. Um das SDK zu erhalten, fügen Sie die `AWSXRayRecorder`-Pakete Ihrer Projektdatei hinzu.

```
<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>
```

Es gibt eine Reihe von Nuget-Paketen, die automatische Instrumentierung für AWS SDKs Entity Framework- und HTTP-Anfragen bieten. Den vollständigen Satz der Konfigurationsoptionen finden Sie unter [AWS X-Ray SDK for .NET](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-dotnet.html) im *AWS X-Ray -Entwicklerhandbuch*.

Nachdem Sie die gewünschten Nuget-Pakete hinzugefügt haben, konfigurieren Sie die automatische Instrumentierung. Es empfiehlt sich, diese Konfiguration außerhalb der Handler-Funktion Ihrer Funktion durchzuführen. So können Sie die Wiederverwendung der Ausführungsumgebung nutzen, um die Leistung Ihrer Funktion zu verbessern. Im folgenden Codebeispiel wird die `RegisterXRayForAllServices` Methode im Funktionskonstruktor aufgerufen, um Instrumentierung für alle AWS SDK-Aufrufe hinzuzufügen.

```
[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)
        };
    }
}
```

## Aktivieren der Nachverfolgung mit der Lambda-Konsole
<a name="dotnet-tracing-console"></a>

Gehen Sie folgendermaßen vor, um die aktive Nachverfolgung Ihrer Lambda-Funktion mit der Konsole umzuschalten:

**So aktivieren Sie die aktive Nachverfolgung**

1. Öffnen Sie die Seite [Funktionen](https://console.aws.amazon.com/lambda/home#/functions) der Lambda-Konsole.

1. Wählen Sie eine Funktion aus.

1. Wählen Sie **Configuration** (Konfiguration) und dann **Monitoring and operations tools** (Überwachungs- und Produktionstools).

1. Wählen Sie unter **Zusätzliche Überwachungstools** die Option **Bearbeiten** aus.

1. Wählen Sie unter **CloudWatch Anwendungssignale und AWS X-Ray** die Option **Enable** for **Lambda Service Traces** aus.

1. Wählen Sie **Speichern**.

## Aktivieren der Nachverfolgung mit der Lambda-API
<a name="dotnet-tracing-api"></a>

Konfigurieren Sie die Ablaufverfolgung für Ihre Lambda-Funktion mit dem AWS CLI oder AWS SDK und verwenden Sie die folgenden API-Operationen:
+ [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)

**Der folgende AWS CLI Beispielbefehl aktiviert die aktive Ablaufverfolgung für eine Funktion namens my-function.**

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

Der Ablaufverfolgungsmodus ist Teil der versionsspezifischen Konfiguration, wenn Sie eine Version Ihrer Funktion veröffentlichen. Sie können den Ablaufverfolgungsmodus für eine veröffentlichte Version nicht ändern.

## Die Ablaufverfolgung wird aktiviert mit CloudFormation
<a name="dotnet-tracing-cloudformation"></a>

Um die Ablaufverfolgung für eine `AWS::Lambda::Function` Ressource in einer CloudFormation Vorlage zu aktivieren, verwenden Sie die `TracingConfig` Eigenschaft.

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

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

Verwenden Sie für eine `AWS::Serverless::Function` Ressource AWS Serverless Application Model (AWS SAM) die `Tracing` Eigenschaft.

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

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

## Interpretieren einer X-Ray-Nachverfolgung
<a name="dotnet-tracing-interpretation"></a>

Ihre Funktion benötigt die Berechtigung zum Hochladen von Trace-Daten zu X-Ray. Wenn Sie die aktive Nachverfolgung in der Lambda-Konsole aktivieren, fügt Lambda der [Ausführungsrolle](lambda-intro-execution-role.md) Ihrer Funktion die erforderlichen Berechtigungen hinzu. Andernfalls fügen Sie die [AWSXRayDaemonWriteAccess](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess)Richtlinie der Ausführungsrolle hinzu.

Nachdem Sie die aktive Nachverfolgung konfiguriert haben, können Sie bestimmte Anfragen über Ihre Anwendung beobachten. Das [X-Ray-Service-Diagramm](https://docs.aws.amazon.com/xray/latest/devguide/aws-xray.html#xray-concepts-servicegraph) zeigt Informationen über Ihre Anwendung und alle ihre Komponenten an. Das folgende Beispiel zeigt eine Anwendung mit zwei Funktionen. Die primäre Funktion verarbeitet Ereignisse und gibt manchmal Fehler zurück. Die zweite Funktion an oberster Stelle verarbeitet Fehler, die in der Protokollgruppe der ersten auftreten, und verwendet das AWS SDK, um X-Ray, Amazon Simple Storage Service (Amazon S3) und Amazon CloudWatch Logs aufzurufen.

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


X-Ray verfolgt nicht alle Anfragen an Ihre Anwendung nach. X-Ray wendet einen Sampling-Algorithmus an, um sicherzustellen, dass die Nachverfolgung effizient ist, und stellt dennoch ein repräsentatives Beispiel aller Anfragen bereit. Die Samplingrate beträgt 1 Anforderung pro Sekunde und 5 Prozent aller weiteren Anforderungen. Sie können die X-Ray-Samplingrate nicht für Ihre Funktionen konfigurieren.

In X-Ray, zeichnet eine *Ablaufverfolgung* Informationen zu einer Anforderung auf, die von einem oder mehreren *Services* verarbeitet wird. Lambda zeichnet 2 Segmente pro Trace auf, wodurch zwei Knoten im Dienstgraphen entstehen. In der folgenden Abbildung werden diese beiden Knoten hervorgehoben:

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


Der erste Knoten auf der linken Seite stellt den Lambda-Service dar, der die Aufrufanforderung empfängt. Der zweite Knoten stellt Ihre spezifische Lambda-Funktion dar. Das folgende Beispiel zeigt eine Nachverfolgung mit diesen zwei Segmenten. Beide heißen **my-function**, aber einer hat einen Ursprung von `AWS::Lambda` und der andere hat einen Ursprung von `AWS::Lambda::Function`. Wenn das `AWS::Lambda`-Segment einen Fehler anzeigt, hatte der Lambda-Service ein Problem. Wenn das `AWS::Lambda::Function`-Segment einen Fehler anzeigt, ist bei Ihrer Funktion ein Problem aufgetreten.

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


Dieses Beispiel erweitert das `AWS::Lambda::Function`-Segment, um seine drei Untersegmente anzuzeigen.

**Anmerkung**  
AWS implementiert derzeit Änderungen am Lambda-Service. Aufgrund dieser Änderungen können geringfügige Unterschiede in Struktur und Inhalt der Systemprotokollmeldungen und Trace-Segmente auftreten, die von verschiedenen Lambda-Funktionen in Ihrem AWS-Konto.  
Der hier gezeigte Beispiel-Trace veranschaulicht das Funktionssegment im alten Stil. Die Unterschiede zwischen den Segmenten im alten und im neuen Stil werden in den folgenden Abschnitten beschrieben.  
Diese Änderungen werden in den kommenden Wochen umgesetzt, und alle Funktionen AWS-Regionen außer China und den GovCloud Regionen werden auf die Verwendung der Protokollnachrichten und Trace-Segmente im neuen Format umgestellt.

Das Funktionssegment im alten Stil enthält die folgenden Untersegmente:
+ **Initialisierung** – Stellt die Zeit dar, die für das Laden Ihrer Funktion und das Ausführen des [Initialisierungscodes](foundation-progmodel.md) aufgewendet wurde. Dieses Untersegment erscheint nur für das erste Ereignis, das jede Instance Ihrer Funktion verarbeitet.
+ **Invocation** (Aufruf) – Stellt die Zeit dar, die beim Ausführen Ihres Handler-Codes vergeht.
+ **Overhead** (Aufwand) – Stellt die Zeit dar, die von der Lambda-Laufzeitumgebung bei der Verarbeitung des nächsten Ereignisses verbraucht wird.

Das Funktionssegment im neuen Stil enthält kein `Invocation`-Untersegment. Stattdessen werden Kundenuntersegmente direkt an das Funktionssegment angehängt. Weitere Informationen über die Struktur der alten und neuen Funktionssegmente finden Sie unter [Grundlegendes zu X-Ray-Ablaufverfolgungen](services-xray.md#services-xray-traces).

Sie können auch HTTP-Clients instrumentieren, SQL-Abfragen aufzeichnen und benutzerdefinierte Untersegmente mit Anmerkungen und Metadaten erstellen. Weitere Informationen finden Sie unter [AWS X-Ray SDK für .NET](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-dotnet.html) im *AWS X-Ray -Entwicklerhandbuch*.

**Preisgestaltung**  
Im Rahmen des kostenlosen Kontingents können Sie X-Ray Tracing jeden Monat bis zu einem bestimmten Limit AWS kostenlos nutzen. Über den Schwellenwert hinaus berechnet X-Ray Gebühren für die Speicherung und den Abruf der Nachverfolgung. Weitere Informationen finden Sie unter [AWS X-Ray Preise](https://aws.amazon.com/xray/pricing/).

# AWS Lambda-Funktions-Testing in C\$1
<a name="dotnet-csharp-testing"></a>

**Anmerkung**  
Im Kapitel [Testen von Funktionen](testing-guide.md) finden Sie eine vollständige Einführung in Techniken und bewährte Methoden für das Testen von Serverless-Lösungen. 

 Beim Testen der Serverless-Funktionen werden herkömmliche Testtypen und -techniken verwendet. Erwägen Sie jedoch auch das Testen der Serverless-Anwendungen als Ganzes. Cloud-basierte Tests bieten das **genaueste** Maß für die Qualität sowohl Ihrer Funktionen als auch Ihrer Serverless-Anwendungen. 

 Eine Serverless-Anwendungsarchitektur umfasst verwaltete Services, die über API-Aufrufe wichtige Anwendungsfunktionen bereitstellen. Aus diesem Grund muss Ihr Entwicklungszyklus automatisierte Tests beinhalten, die bei der Interaktion Ihrer Funktionen und Services die Funktionalität überprüfen. 

 Wenn Sie keine cloud-basierten Tests erstellen, können aufgrund von Unterschieden zwischen Ihrer lokalen Umgebung und der bereitgestellten Umgebung Probleme auftreten. Ihr kontinuierlicher Integrationsprozess muss Tests anhand einer Reihe von Ressourcen durchführen, die in der Cloud bereitgestellt werden, bevor Ihr Code in die nächste Bereitstellungsumgebung wie QA, Staging oder Produktion übertragen wird. 

 Lesen Sie diesen kurzen Leitfaden weiter, um weitere Informationen zu Teststrategien für Serverless-Anwendungen zu erhalten, oder besuchen Sie das [Serverless Test Samples Repository](https://github.com/aws-samples/serverless-test-samples), um praktische Beispiele zu finden, die sich speziell auf die gewählte Sprache und Laufzeit beziehen. 

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

 Für Serverless-Tests schreiben Sie weiterhin *Einheiten*-, *Integrations*- und *End-to-End*-Tests. 
+ **Einheitentests** — Tests, die an einem isolierten Codeblock ausgeführt werden. Zum Beispiel die Überprüfung der Geschäftslogik zur Berechnung der Bereitstellungskosten für einen bestimmten Artikel und Bestimmungsort.
+ **Integrationstests** — Tests, an denen zwei oder mehr Komponenten oder Dienste beteiligt sind, die interagieren, in der Regel in einer Cloud-Umgebung. Bei der Überprüfung einer Funktion werden beispielsweise Ereignisse aus einer Warteschlange verarbeitet.
+ **End-to-End-Tests** — Tests, die das Verhalten einer gesamten Anwendung überprüfen. Stellen Sie beispielsweise sicher, dass die Infrastruktur korrekt eingerichtet ist und die Ereignisse zwischen den Services wie erwartet ablaufen, um die Bestellungen der Kunden aufzuzeichnen.

## Testen Ihrer Serverless-Anwendungen
<a name="dotnet-csharp-testing-techniques-for-serverless-applications"></a>

 In der Regel verwenden Sie eine Mischung aus verschiedenen Ansätzen, um Ihren Serverless-Anwendungscode zu testen, einschließlich Tests in der Cloud, Tests mit Mock-Code und gelegentlich Tests mit Emulatoren. 

### Testen in der Cloud
<a name="dotnet-csharp-testing-in-the-cloud"></a>

 Das Testen in der Cloud ist für alle Testphasen von Nutzen, einschließlich Einheitentests, Integrationstests und End-to-End-Tests. Sie führen Tests für Code durch, der in der Cloud bereitgestellt wird und mit cloud-basierten Services interagiert. Dieser Ansatz bietet das **genaueste** Maß für die Qualität Ihres Codes. 

 Eine bequeme Möglichkeit, Ihre Lambda-Funktion in der Cloud zu debuggen, ist die Verwendung der Konsole mit einem Testereignis. Ein *Testereignis* ist eine JSON-Eingabe für Ihre Funktion. Wenn Ihre Funktion keine Eingabe erfordert, kann das Ereignis ein leeres JSON-Dokument `({})` sein. Die Konsole bietet Beispielereignisse für eine Vielzahl von Service-Integrationen. Nachdem Sie ein Ereignis in der Konsole erstellt haben, können Sie es mit Ihrem Team teilen, um das Testen einfacher und einheitlicher zu gestalten. 

**Anmerkung**  
Das [Testen einer Funktion in der Konsole](testing-functions.md) ist ein schneller Einstieg, aber die Automatisierung Ihrer Testzyklen gewährleistet die Anwendungsqualität und die Entwicklungsgeschwindigkeit. 

### Test-Tools
<a name="dotnet-csharp-testing-tools"></a>

Um Ihren Entwicklungszyklus zu beschleunigen, gibt es eine Reihe von Tools und Techniken, die Sie beim Testen Ihrer Funktionen verwenden können. [AWS SAMAccelerate](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/using-sam-cli-sync.html) und [AWS CDKWatch Mode](https://docs.aws.amazon.com/cdk/v2/guide/cli.html#cli-deploy-watch) reduzieren beispielsweise beide die Zeit, die für die Aktualisierung von Cloud-Umgebungen benötigt wird.

Die Art und Weise, wie Sie Ihren Lambda-Funktionscode definieren, macht es einfach, Komponententests hinzuzufügen. Lambda benötigt einen öffentlichen, parameterlosen Konstruktor, um Ihre Klasse zu initialisieren. Durch die Einführung eines zweiten, internen Konstruktors haben Sie die Kontrolle über die Abhängigkeiten, die Ihre Anwendung verwendet.

```
[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)
        };
    }
}
```

Um einen Test für diese Funktion zu schreiben, können Sie eine neue Instance Ihrer `Function`-Klasse initialisieren und eine simulierte Implementierung von `IDatabaseRepository` übergeben. Die folgenden Beispiele verwenden `XUnit`, `Moq` und `FluentAssertions`, um einen einfachen Test zu schreiben, der sicherstellt, dass `FunctionHandler` einen 200-Statuscode zurückgibt.

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

Ausführlichere Beispiele, einschließlich Beispiele für asynchrone Tests, finden Sie im [Repository für .NET-Testbeispiele](https://github.com/aws-samples/serverless-test-samples/tree/main/dotnet-test-samples) auf GitHub.