

# Creación de funciones Lambda con C\$1
<a name="lambda-csharp"></a>

Puede ejecutar la aplicación .NET en Lambda mediante el tiempo de ejecución administrado de .NET 8, un tiempo de ejecución personalizado o una imagen de contenedor. Una vez compilado el código de la aplicación, puede implementarlo en Lambda como un archivo.zip o una imagen de contenedor. Lambda proporciona los siguientes tiempos de ejecución para lenguajes .NET:


| Nombre | Identificador | Sistema operativo | Fecha de baja | Bloqueo de la función Crear | Bloqueo de la función Actualizar | 
| --- | --- | --- | --- | --- | --- | 
|  .NET 10  |  `dotnet10`  |  Amazon Linux 2023  |   14 de noviembre de 2028   |   14 de diciembre de 2028   |   15 de enero de 2029   | 
|  .NET 9 (solo contenedor)  |  `dotnet9`  |  Amazon Linux 2023  |   10 de noviembre de 2026   |   No programado   |   No programado   | 
|  .NET 8  |  `dotnet8`  |  Amazon Linux 2023  |   10 de noviembre de 2026   |   10 de diciembre de 2026   |   11 de enero de 2027   | 

## Configuración del entorno de desarrollo de .NET
<a name="csharp-dev-env"></a>

Para desarrollar y construir sus funciones de Lambda, puede usar cualquiera de los entornos de desarrollo integrado (IDE) de .NET, incluidos Microsoft Visual Studio, Visual Studio Code, y JetBrains Rider. Para simplificar su experiencia de desarrollo, AWS proporciona un conjunto de plantillas de proyecto .NET, así como la interfaz de línea de comandos (CLI) `Amazon.Lambda.Tools`.

Ejecute los siguientes comandos de la CLI de .NET para instalar estas plantillas de proyecto y las herramientas de línea de comandos.

### Instalación de las plantillas del proyecto .NET
<a name="csharp-dev-env-templates"></a>

Para instalar las plantillas de proyecto, ejecute el siguiente comando:

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

### Instalación y actualización de las herramientas de la CLI
<a name="csharp-dev-env-cli-tools"></a>

Ejecute los siguientes comandos para instalar, actualizar y desinstalar la CLI de `Amazon.Lambda.Tools`.

Para instalar las herramientas de línea de comandos:

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

Para actualizar las herramientas de línea de comandos:

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

Para desinstalar las herramientas de línea de comandos:

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

# Definir el controlador de funciones de Lambda en C\$1
<a name="csharp-handler"></a>

El *controlador* de la función de Lambda es el método del código de la función que procesa eventos. Cuando se invoca una función, Lambda ejecuta el método del controlador. La función se ejecuta hasta que el controlador devuelve una respuesta, se cierra o se agota el tiempo de espera.

En esta página se describe cómo se trabaja con los controladores de funciones de Lambda en C\$1 para usar el tiempo de ejecución administrado de. NET, incluidas las opciones para la configuración del proyecto, las convenciones de nomenclatura y las prácticas recomendadas. En esta página también se incluye el ejemplo de una función de Lambda de C\$1 que recibe información sobre un pedido, genera un recibo en un archivo de texto y coloca este archivo en un bucket de Amazon Simple Storage Service (S3). Para obtener información sobre cómo implementar la función después de escribirla, consulte [Crear e implementar funciones de Lambda C\$1 con archivos de archivo .zip](csharp-package.md) o [Implementar funciones de Lambda .NET con imágenes de contenedor](csharp-image.md).

**Topics**
+ [

## Configuración del proyecto del controlador de C\$1
](#csharp-handler-setup)
+ [

## Ejemplo de código de una función de Lambda en C\$1
](#csharp-example-code)
+ [

## Controladores de bibliotecas de clases
](#csharp-class-library-handlers)
+ [

## Controladores de conjuntos ejecutables
](#csharp-executable-assembly-handlers)
+ [

## Firmas de controlador válidas para funciones de C\$1
](#csharp-handler-signatures)
+ [

## Convenciones de nomenclatura de controladores
](#csharp-handler-naming)
+ [

## Serialización en C\$1 de las funciones de Lambda
](#csharp-handler-serializer)
+ [

## Funciones basadas en archivos
](#csharp-file-based-functions)
+ [

## Acceso y uso del objeto de contexto de Lambda
](#csharp-example-context)
+ [

## Uso de la versión 3 de SDK para .NET en el controlador
](#csharp-example-sdk-usage)
+ [

## Acceso a las variables de entorno
](#csharp-example-envvars)
+ [

## Uso del estado global
](#csharp-handler-state)
+ [

## Simplifique el código de funciones con el marco de anotaciones Lambda
](#csharp-handler-annotations)
+ [

## Prácticas recomendadas de codificación para las funciones de Lambda en C\$1
](#csharp-best-practices)

## Configuración del proyecto del controlador de C\$1
<a name="csharp-handler-setup"></a>

Cuando se trabaja con funciones de Lambda en C\$1, el proceso implica escribir el código y, posteriormente, implementarlo en Lambda. Existen dos modelos de ejecución diferentes para ejecutar funciones de Lambda en .NET: el enfoque de biblioteca de clases y el enfoque de conjuntos ejecutables.

En el enfoque de biblioteca de clases, se empaqueta el código de función como un conjunto de .NET (`.dll`) y se implementa en Lambda con el tiempo de ejecución administrado de .NET (`dotnet8`). Para el nombre del controlador, Lambda espera una cadena en el formato `AssemblyName::Namespace.Classname::Methodname`. Durante la fase de inicialización de la función, se inicializa la clase de la función y se ejecuta cualquier código del constructor.

En el enfoque de conjuntos ejecutables, se usa la [característica de instrucciones de nivel superior](https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/top-level-statements) que se introdujo por primera vez en C\$1 9. Este enfoque genera un conjunto ejecutable que Lambda ejecuta cada vez que recibe un comando invoke para su función. En este enfoque, también se usa el tiempo de ejecución administrado de .NET (`dotnet8`). Para el nombre del controlador, debe proporcionar a Lambda el nombre del conjunto ejecutable que se va a ejecutar.

En el ejemplo principal de esta página se ilustra el enfoque de biblioteca de clases. Puede inicializar su proyecto de Lambda en C\$1 de varias formas, pero la forma más sencilla es usar la CLI de .NET con la CLI de `Amazon.Lambda.Tools`. Configure la CLI de `Amazon.Lambda.Tools` siguiendo los pasos que se indican en [Configuración del entorno de desarrollo de .NET](lambda-csharp.md#csharp-dev-env). A continuación, inicialice el proyecto con el siguiente comando:

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

Este comando genera la siguiente estructura de archivos:

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

En esta estructura de archivos, la lógica del controlador principal de la función reside en el archivo `Function.cs`.

## Ejemplo de código de una función de Lambda en C\$1
<a name="csharp-example-code"></a>

El siguiente ejemplo de código de función de Lambda en C\$1 recibe información sobre un pedido, genera un recibo en un archivo de texto y coloca este archivo en un bucket de Amazon S3.

**Example `Function.cs`Función de Lambda**  

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

Este archivo `Function.cs` contiene las siguientes secciones de código:
+ Instrucciones de `using`: úselas para importar las clases de C\$1 que requiere la función de Lambda.
+ `[assembly: LambdaSerializer(...)]`: `LambdaSerializer` es un atributo de conjunto que indica a Lambda que convierta automáticamente las cargas útiles de eventos JSON en objetos de C\$1 antes de pasarlos a su función.
+ `namespace ExampleLambda`: esto define el espacio de nombres. En C\$1, el nombre del espacio de nombres no tiene que coincidir con el nombre del archivo.
+ `public class Order {...}`: esto define la forma del evento de entrada esperado.
+ `public class OrderHandler {...}`: esto define su clase de C\$1. Dentro de ella, definirá el método de controlador principal y cualquier otro método auxiliar.
+ `private static readonly AmazonS3Client s3Client = new();`: esto inicializa un cliente de Amazon S3 con la cadena de proveedores de credenciales predeterminada, fuera del método del controlador principal. Esto hace que Lambda ejecute este código durante la [fase de inicialización](lambda-runtime-environment.md#runtimes-lifecycle-ib).
+ `public async ... HandleRequest (Order order, ILambdaContext context)`: este es el **método del controlador principal**, que contiene la lógica principal de la aplicación.
+ `private async Task UploadReceiptToS3(...) {}`: este es un método auxiliar al que hace referencia el método del controlador principal `handleRequest`.

Dado que esta función requiere un cliente del SDK de Amazon S3, debe agregarlo a las dependencias del proyecto. Para hacerlo, navegue a `src/ExampleCS` y ejecute el siguiente comando:

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

### Cómo agregar información de metadatos a aws-lambda-tools-defaults.json
<a name="csharp-metadata-example"></a>

De forma predeterminada, el archivo `aws-lambda-tools-defaults.json` generado no contiene información de `profile` ni `region` para su función. Además, actualice la cadena `function-handler` al valor correcto (`ExampleCS::ExampleLambda.OrderHandler::HandleRequest`). Puede llevar a cabo esta actualización manualmente y agregar los metadatos necesarios para usar un perfil de credenciales y una región específicos para su función. Por ejemplo, el archivo `aws-lambda-tools-defaults.json` debe ser similar al siguiente ejemplo:

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

Para que esta función se ejecute correctamente, su [rol de ejecución](lambda-intro-execution-role.md) debe permitir la acción `s3:PutObject`. Además, asegúrese de definir la variable de entorno `RECEIPT_BUCKET`. Tras una invocación correcta, el bucket de Amazon S3 debe contener un archivo de recibo.

## Controladores de bibliotecas de clases
<a name="csharp-class-library-handlers"></a>

En el [ejemplo de código](#csharp-example-code) principal de esta página se ilustra un controlador de biblioteca de clases. Los controladores de biblioteca de clases tienen la siguiente estructura:

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

namespace NAMESPACE;

...

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

Al crear una función de Lambda, debe proporcionar a Lambda información sobre el controlador de la función en forma de cadena en el [campo Handler](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-Handler). Esto le indica a Lambda qué método del código debe ejecutar cuando se invoque la función. En C\$1, para los controladores de biblioteca de clases, el formato de la cadena del controlador es `ASSEMBLY::TYPE::METHOD`, donde:
+ `ASSEMBLY` es el nombre del archivo de conjunto de .NET para la aplicación. Si usa la CLI de `Amazon.Lambda.Tools` para compilar la aplicación y no establece el nombre del conjunto con la propiedad `AssemblyName` del archivo `.csproj`, entonces `ASSEMBLY` será simplemente el nombre del archivo `.csproj`.
+ `TYPE` es el nombre completo del tipo de controlador, que es `NAMESPACE.CLASSNAME`.
+ `METHOD` es el nombre del método de controlador principal en el código, que es `METHODNAME`.

En el ejemplo de código que se muestra en esta página, si se nombra el conjunto como `ExampleCS`, entonces la cadena del controlador sería `ExampleCS::ExampleLambda.OrderHandler::HandleRequest`.

## Controladores de conjuntos ejecutables
<a name="csharp-executable-assembly-handlers"></a>

También puede definir las funciones de Lambda en C\$1 como un conjunto ejecutable. Los controladores de conjuntos ejecutables usan la característica de instrucciones de nivel superior de C\$1, en la que el compilador genera el método `Main()` y coloca el código de la función en él. Cuando se utilizan ensamblados ejecutables, se debe iniciar el tiempo de ejecución de Lambda. Para ello, se usa el método `LambdaBootstrapBuilder.Create` en el código. Las entradas de este método son la función de controlador principal y el serializador de Lambda que se usará. A continuación se muestra un ejemplo de un controlador de conjunto ejecutable en 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)
    };
};
```

En el [campo Handler](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html#lambda-CreateFunction-request-Handler) de controladores de conjuntos ejecutables, la cadena de controlador que le dice a Lambda cómo ejecutar el código es el nombre del conjunto. En este ejemplo, es `GetProductHandler`.

## Firmas de controlador válidas para funciones de C\$1
<a name="csharp-handler-signatures"></a>

En C\$1, las firmas de controlador de Lambda válidas aceptan entre 0 y 2 argumentos. Por lo general, la firma de su controlador tiene dos argumentos, como se muestra en el ejemplo principal:

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

Al proporcionar dos argumentos, el primero debe ser la entrada del evento y el segundo debe ser el objeto de contexto de Lambda. Ambos argumentos son opcionales. Por ejemplo, las siguientes firmas de controlador de Lambda también son válidas en C\$1:
+ `public async Task<string> HandleRequest()`
+ `public async Task<string> HandleRequest(Order order)`
+ `public async Task<string> HandleRequest(ILambdaContext context)`

Además de la sintaxis básica de la firma del controlador, existen algunas restricciones adicionales:
+ No puede usar la palabra clave `unsafe` en la firma del controlador. Sin embargo, puede usar el contexto `unsafe` dentro del método del controlador y sus dependencias. Para obtener más información, consulte [unsafe (Referencia de C\$1)](https://msdn.microsoft.com/en-us/library/chfa2zb8.aspx) en el sitio web de documentación de Microsoft.
+ El controlador no puede usar la palabra clave `params` ni usar `ArgIterator` como parámetro de entrada o retorno. Estas palabras clave admiten un número variable de parámetros. El número máximo de argumentos que el controlador puede aceptar es dos.
+ El controlador no puede ser un método genérico. En otras palabras, no puede usar parámetros de tipo genérico como `<T>`.
+ Lambda no admite controladores asíncronos con `async void` en la firma.

## Convenciones de nomenclatura de controladores
<a name="csharp-handler-naming"></a>

Los controladores de Lambda en C\$1 no tienen restricciones de nomenclatura estrictas. Sin embargo, debe asegurarse de proporcionar la cadena de controlador correcta a Lambda al implementar la función. La cadena de controlador correcta depende de si está implementando un [controlador de biblioteca de clases](#csharp-class-library-handlers) o un [controlador de conjunto ejecutable](#csharp-executable-assembly-handlers).

Aunque puede usar cualquier nombre para su controlador, los nombres de las funciones en C\$1 generalmente están en PascalCase. Además, aunque no es necesario que el nombre del archivo coincida con el nombre de la clase o el nombre del controlador, generalmente se recomienda usar un nombre de archivo como `OrderHandler.cs` si el nombre de su clase es `OrderHandler`. Por ejemplo, puede modificar el nombre del archivo en este ejemplo de `Function.cs` a `OrderHandler.cs`.

## Serialización en C\$1 de las funciones de Lambda
<a name="csharp-handler-serializer"></a>

El formato de entrada más común y estándar de las funciones de Lambda es JSON. En este ejemplo, la función espera una entrada similar a la siguiente:

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

En C\$1, puede definir la forma del evento de entrada esperado en una clase. En este ejemplo, definimos la clase `Order` para modelar esta entrada:

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

Si las funciones de Lambda que utilizan tipos de entrada o salida distintos de un objeto `Stream`, debe agregar una biblioteca de serialización a la aplicación. Esto le permite convertir la entrada JSON en una instancia de la clase que haya definido. Hay dos métodos de serialización para las funciones de C\$1 en Lambda: la serialización basada en la reflexión y la serialización generada por el origen.

### Serialización basada en la reflexión
<a name="csharp-reflection-based-serialization"></a>

AWS proporciona bibliotecas prediseñadas que puede agregar rápidamente a su aplicación. Estas bibliotecas implementan la serialización mediante [reflexión](https://learn.microsoft.com/en-us/dotnet/csharp/advanced-topics/reflection-and-attributes/). Use uno de los siguientes paquetes para implementar la serialización basada en la reflexión:
+ `Amazon.Lambda.Serialization.SystemTextJson`: en el backend, este paquete usa `System.Text.Json` para efectuar tareas de serialización.
+ `Amazon.Lambda.Serialization.Json`: en el backend, este paquete usa `Newtonsoft.Json` para efectuar tareas de serialización.

También puede crear su propia biblioteca de serialización mediante la implementación de la interfaz `ILambdaSerializer`, que está disponible como parte de la biblioteca `Amazon.Lambda.Core`. Esta interfaz define dos métodos:
+ `T Deserialize<T>(Stream requestStream);`

  Puede implementar este método para deserializar la carga de solicitud desde la API `Invoke` en el objeto que se pasa al controlador de la función de Lambda.
+ `T Serialize<T>(T response, Stream responseStream);`

  Puede implementar este método para serializar el resultado que devuelve el controlador de la función de Lambda en la carga de respuesta que devuelve la API de operación `Invoke`.

En el ejemplo principal de esta página se usa la serialización basada en la reflexión. La serialización basada en la reflexión funciona de forma inmediata con AWS Lambda y no requiere ninguna configuración adicional, lo que la convierte en una buena opción por su simplicidad. Sin embargo, requiere un mayor uso de memoria de la función. También es posible que vea latencias de funciones más altas debido a la reflexión en tiempo de ejecución.

### Serialización generada por el origen
<a name="csharp-source-generated-serialization"></a>

Con la serialización generada por el origen, el código de serialización se genera en tiempo de compilación. Esto elimina la necesidad de reflexión y puede mejorar el rendimiento de la función. Para usar la serialización generada en el origen en la función, haga lo siguiente:
+ Cree una nueva clase parcial que herede de `JsonSerializerContext` al añadir atributos `JsonSerializable` para todos los tipos que requieran serialización o deserialización.
+ Configurar la `LambdaSerializer` para usar un `SourceGeneratorLambdaJsonSerializer<T>`.
+ Actualice cualquier serialización o deserialización manual del código de su aplicación para usar la clase recién creada.

En el siguiente ejemplo se muestra cómo puede modificar el ejemplo principal de esta página, que usa la serialización basada en la reflexión, para usar en su lugar la serialización generada por el origen.

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

...

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

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

public class OrderHandler
{

    ...

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

}
```

La serialización generada por el origen requiere más configuración que la serialización basada en la reflexión. Sin embargo, las funciones que usan la serialización generada por el origen suelen usar menos memoria y tienen un mejor rendimiento debido a la generación de código en tiempo de compilación. Para ayudar a eliminar los [arranques en frío](lambda-runtime-environment.md#cold-start-latency) de las funciones, considere la posibilidad de cambiar a la serialización generada por el origen.

**nota**  
Si desea usar la [compilación anticipada (AOT)](dotnet-native-aot.md) nativa con Lambda, debe usar la serialización generada por el origen.

## Funciones basadas en archivos
<a name="csharp-file-based-functions"></a>

Las aplicaciones basadas en archivos, introducidas en .NET 10, permiten crear aplicaciones .NET a partir de un único archivo `.cs`, sin un archivo `.csproj` ni una estructura de directorios. Lambda admite funciones basadas en archivos, empezando por .NET 10. Estas ofrecen una forma simplificada y ligera de crear funciones de Lambda en C\$1.

La forma más rápida de empezar a crear una función de Lambda basada en archivos en C\$1 es utilizar el paquete `Amazon.Lambda.Templates`. Para instalar este paquete, ejecute el comando siguiente:

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

A continuación, cree una función de Lambda basada en archivos en C\$1 como ejemplo:

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

Las funciones basadas en archivos utilizan [controladores de conjuntos ejecutables](#csharp-executable-assembly-handlers). Por lo tanto, debe incluir el paquete NuGet `Amazon.Lambda.RuntimeSupport` y utilizar el método `LambdaBootstrapBuilder.Create` para registrar la función controladora de .NET para el tipo de evento e iniciar el cliente del tiempo de ejecución de .NET para Lambda.

Las funciones basadas en archivos utilizan Native AOT de .NET de forma predeterminada, lo que requiere una serialización generada por el origen. Puede deshabilitar Native AOT especificando `#:property PublishAot=false` en el archivo de origen. Para obtener más información sobre cómo utilizar Native AOT en Lambda, consulte [Compilar el código de una función de Lambda .NET en un formato de tiempo de ejecución nativo](dotnet-native-aot.md).

## Acceso y uso del objeto de contexto de Lambda
<a name="csharp-example-context"></a>

El [objeto de contexto](csharp-context.md) de Lambda contiene información sobre la invocación, la función y el entorno de ejecución. En este ejemplo, el objeto de contexto es de tipo `Amazon.Lambda.Core.ILambdaContext` y es el segundo argumento de la función del controlador principal.

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

El objeto de contexto es una entrada opcional. Para obtener más información sobre las firmas de controlador válidas, consulte [Firmas de controlador válidas para funciones de C\$1](#csharp-handler-signatures).

El objeto de contexto es útil para generar registros de funciones en Amazon CloudWatch. Puede usar el método `context.getLogger()` para obtener un objeto `LambdaLogger` para el registro. En este ejemplo, podemos usar el registrador para registrar un mensaje de error si el procesamiento falla por cualquier motivo:

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

Además del registro, también puede usar el objeto de contexto para supervisar las funciones. Para obtener más información acerca del objeto de contexto, consulte [Uso del objeto de contexto de Lambda para recuperar información de funciones de C\$1](csharp-context.md).

## Uso de la versión 3 de SDK para .NET en el controlador
<a name="csharp-example-sdk-usage"></a>

A menudo, utilizará las funciones de Lambda para interactuar con otros recursos de AWS o actualizarlos. La forma más sencilla de interactuar con estos recursos es usar la versión 3 de SDK para .NET.

**nota**  
La versión 2 de SDK para .NET se ha quedado obsoleto. Se recomienda que use únicamente la versión 3 de SDK para .NET a partir de ahora.

Puede agregar dependencias del SDK a su proyecto mediante el siguiente comando de `Amazon.Lambda.Tools`:

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

Por ejemplo, en el ejemplo principal de esta página, debemos usar la API de Amazon S3 para cargar un recibo en S3. Podemos importar el cliente del SDK de Amazon S3 mediante el siguiente comando:

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

Este comando agrega la dependencia a su proyecto. Debería ver una línea similar a la siguiente en el archivo `.csproj` de su proyecto:

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

Luego, importe las dependencias directamente en el código de C\$1:

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

El ejemplo de código inicializa un cliente de Amazon S3 (mediante la [cadena de proveedores de credenciales predeterminada](https://docs.aws.amazon.com/sdkref/latest/guide/standardized-credentials.html)) de la siguiente manera:

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

En este ejemplo, inicializamos el cliente de Amazon S3 fuera de la función del controlador principal para evitar tener que inicializarlo cada vez que invocamos nuestra función. Después de inicializar el cliente del SDK, podrá usarlo para interactuar con otros servicios de AWS. El código de ejemplo llama a la API `PutObject` de Amazon S3 de la siguiente manera:

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

await s3Client.PutObjectAsync(putRequest);
```

## Acceso a las variables de entorno
<a name="csharp-example-envvars"></a>

En el código del controlador, puede hacer referencia a cualquier [variable de entorno](configuration-envvars.md) mediante el método `System.Environment.GetEnvironmentVariable`. En este ejemplo, se hace referencia a la variable de entorno `RECEIPT_BUCKET` definida mediante las siguientes líneas de código:

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

## Uso del estado global
<a name="csharp-handler-state"></a>

Lambda ejecuta su código estático y el constructor de clases durante la [fase de inicialización](lambda-runtime-environment.md#runtimes-lifecycle-ib) antes de invocar la función por primera vez. Los recursos que se crean durante la inicialización permanecen en la memoria entre las invocaciones, por lo que evita tener que crearlos cada vez que invoca la función.

En el código de ejemplo, el código de inicialización del cliente S3 está fuera del método del controlador principal. El tiempo de ejecución inicializa el cliente antes de que la función gestione su primer evento, lo que puede provocar tiempos de procesamiento más largos. Los eventos posteriores son mucho más rápidos porque Lambda no necesita volver a inicializar el cliente.

## Simplifique el código de funciones con el marco de anotaciones Lambda
<a name="csharp-handler-annotations"></a>

[Lambda Annotations](https://www.nuget.org/packages/Amazon.Lambda.Annotations) es un marco para .NET 8 que permite escribir funciones Lambda en C\$1 de forma más sencilla. El marco de anotaciones usa [generadores de origen](https://learn.microsoft.com/en-us/dotnet/csharp/roslyn-sdk/source-generators-overview) para generar código que se traduce del modelo de programación de Lambda al código simplificado. Con el marco de anotaciones, puede reemplazar gran parte del código de una función de Lambda escrita con el modelo de programación normal. El código escrito con el marco utiliza expresiones más sencillas que le permiten centrarse en la lógica empresarial. Consulte [Amazon.Lambda.Annotations](https://www.nuget.org/packages/Amazon.Lambda.Annotations) en la documentación de NuGet para ver ejemplos.

Para ver un ejemplo de una aplicación completa que usa anotaciones de Lambda, consulte el ejemplo de [PhotoAssetManager](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3/cross-service/PhotoAssetManager) en el repositorio de `awsdocs/aws-doc-sdk-examples` de GitHub. El archivo `Function.cs` principal en el directorio `PamApiAnnotations` usa anotaciones de Lambda. A modo de comparación, el directorio `PamApi` tiene archivos equivalentes escritos con el modelo de programación normal de Lambda.

### Inyección de dependencias con el marco de anotaciones Lambda
<a name="csharp-handler-annotations-injection"></a>

También puede utilizar el marco de anotaciones de Lambda para añadir una inyección de dependencias a las funciones de Lambda mediante una sintaxis con la que esté familiarizado. Al añadir un atributo `[LambdaStartup]` a un archivo `Startup.cs`, la estructura de anotaciones Lambda generará el código necesario en tiempo de compilación.

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

La función de Lambda puede inyectar servicios mediante la inyección de un constructor o mediante la inyección en métodos individuales mediante el atributo `[FromServices]`.

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

namespace GetProductHandler;

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

## Prácticas recomendadas de codificación para las funciones de Lambda en C\$1
<a name="csharp-best-practices"></a>

Siga las directrices de la siguiente lista para utilizar las prácticas recomendadas de codificación al crear sus funciones de Lambda:
+ **Separe el controlador de Lambda de la lógica del núcleo.** Esto le permite probar las distintas unidades de la función con mayor facilidad.
+ **Controle las dependencias del paquete de implementación de la función. ** El entorno de ejecución AWS Lambda contiene varias bibliotecas. Para disponer del conjunto más reciente de características y actualizaciones de seguridad, Lambda actualizará periódicamente estas bibliotecas. Estas actualizaciones pueden introducir cambios sutiles en el comportamiento de la función de Lambda. Para disponer de un control total de las dependencias que utiliza la función, empaquete todas las dependencias con el paquete de implementación. 
+ **Minimice la complejidad de las dependencias.** Son preferibles los marcos de trabajo más sencillos, ya que se cargan rápidamente al arrancar el [entorno de ejecución](lambda-runtime-environment.md).
+ **Minimice el tamaño del paquete de implementación de acuerdo con las necesidades de su tiempo de ejecución. ** Esto reducirá la cantidad de tiempo que tarda el paquete de implementación en descargarse y desempaquetarse antes de la invocación. En las funciones creadas en .NET, evite cargar toda la biblioteca del AWS SDK como parte del paquete de implementación. En lugar de ello, cree dependencias selectivas de los módulos que seleccionen los componentes del SDK que necesita (por ejemplo, DynamoDB, módulos del SDK de Amazon S3 y bibliotecas básicas de Lambda). 

**Reutilice el entorno de ejecución para mejorar el rendimiento de la función.** Inicialice los clientes de SDK y las conexiones de base de datos fuera del controlador de funciones y almacene localmente en caché los recursos estáticos en el directorio `/tmp`. Las invocaciones posteriores procesadas por la misma instancia de su función pueden reutilizar estos recursos. Esto ahorra costes al reducir el tiempo de ejecución de la función.

Para evitar posibles filtraciones de datos entre las invocaciones, no utilice el entorno de ejecución para almacenar datos de usuario, eventos u otra información con implicaciones de seguridad. Si su función se basa en un estado mutable que no se puede almacenar en la memoria dentro del controlador, considere crear una función independiente o versiones independientes de una función para cada usuario.

**Utilice una directiva keep-alive para mantener conexiones persistentes.** Lambda purga las conexiones inactivas a lo largo del tiempo. Si intenta reutilizar una conexión inactiva al invocar una función, se producirá un error de conexión. Para mantener la conexión persistente, use la directiva keep-alive asociada al tiempo de ejecución. Para ver un ejemplo, consulte [Reutilización de conexiones con Keep-Alive en Node.js](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/node-reusing-connections.html).

**Utilice [variables de entorno](configuration-envvars.md) para pasar parámetros operativos a su función.** Por ejemplo, si está escribiendo en un bucket de Amazon S3, en lugar de codificar de forma rígida el nombre del bucket, configúrelo como una variable de entorno.

**Evite utilizar invocaciones recursivas** en la función de Lambda, en las que la función se invoca a sí misma o inicia un proceso que puede volver a invocarla. Esto podría producir un volumen no intencionado de invocaciones de la función y costos elevados. Si observa un volumen imprevisto de invocaciones, establezca la simultaneidad reservada de funciones en `0` inmediatamente para limitar todas las invocaciones de la función mientras actualiza el código.

**No utilice API no documentadas y no públicas** en el código de la función de Lambda. Para tiempos de ejecución administrados de AWS Lambda, Lambda aplica periódicamente actualizaciones funcionales y de seguridad a las API internas de Lambda. Estas actualizaciones de las API internas pueden ser incompatibles con versiones anteriores, lo que conlleva consecuencias no deseadas, como errores de invocación si su función depende de estas API no públicas. Consulte la [referencia de la API](https://docs.aws.amazon.com/lambda/latest/api/welcome.html) para obtener una lista de las API disponibles públicamente.

**Escriba el código idempotente.** Escribir el código idempotente para las funciones garantiza que los eventos duplicados se gestionen de la misma manera. El código debe validar y gestionar correctamente los eventos duplicados. Para obtener más información, consulte [¿Cómo puedo hacer que mi función de Lambda sea idempotente?](https://aws.amazon.com/premiumsupport/knowledge-center/lambda-function-idempotent/).

# Crear e implementar funciones de Lambda C\$1 con archivos de archivo .zip
<a name="csharp-package"></a>

Un paquete de implementación .NET (archivo de archivo .zip) contiene el ensamblado compilado de su función junto con todas sus dependencias de ensamblado. El paquete también contiene un archivo `proj.deps.json`. Esto indica al tiempo de ejecución .NET todas las dependencias de su función y un archivo `proj.runtimeconfig.json`, que se utiliza para configurar el tiempo de ejecución.

Para implementar funciones individuales de Lambda, puede usar la `Amazon.Lambda.Tools` CLI de .NET Lambda Global. El uso del comando `dotnet lambda deploy-function` crea automáticamente un paquete de implementación .zip y lo implementa en Lambda. Sin embargo, le recomendamos que utilice marcos como AWS Serverless Application Model (AWS SAM) o el AWS Cloud Development Kit (AWS CDK) para implementar sus aplicaciones.NET en AWS.

Las aplicaciones sin servidor suelen incluir una combinación de funciones de Lambda y otros servicios administrados de Servicios de AWS que trabajan juntos para realizar una tarea empresarial determinada. AWS SAM y AWS CDK simplifican la creación e implementación de funciones de Lambda con otros Servicios de AWS a escala. La [especificación de plantillas de AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification.html) proporciona una sintaxis sencilla y organizada para describir las funciones de Lambda, las API, los permisos, las configuraciones y los otros recursos de AWS que constituyen la aplicación sin servidor. Con [AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/home.html) puede definir la infraestructura de nube como código para ayudarle a crear aplicaciones fiables, escalables y rentables en la nube mediante marcos y lenguajes de programación modernos, como .NET. Tanto AWS CDK como AWS SAM utilizan la CLI de .NET Lambda Global para empaquetar sus funciones.

Si bien es posible utilizar [Capas de Lambda](chapter-layers.md) con funciones en C\$1 al [utilizar la CLI de.NET Core](csharp-package-cli.md#csharp-layers), se recomienda que no lo haga. Las funciones en C\$1 que utilizan capas cargan de forma manual los ensamblajes compartidos en la memoria durante el [Fase "init"](lambda-runtime-environment.md#runtimes-lifecycle-ib), lo que puede aumentar los tiempos de arranque en frío. En su lugar, incluya todo el código compartido en el momento de la compilación para evitar el impacto en el rendimiento de la carga de los ensamblajes durante el tiempo de ejecución.

En las siguientes secciones, encontrará instrucciones para crear e implementar funciones de Lamba .NET mediante AWS SAM, AWS CDK y la CLI de .NET Lambda Global y la CLI.

**Topics**
+ [

# Uso de la CLI de .NET Lambda Global
](csharp-package-cli.md)
+ [

# Implemente las funciones de Lambda C\$1 utilizando AWS SAM
](csharp-package-sam.md)
+ [

# Implemente las funciones de Lambda C\$1 utilizando AWS CDK
](csharp-package-cdk.md)
+ [

# Implementación de aplicaciones ASP .NET
](csharp-package-asp.md)

# Uso de la CLI de .NET Lambda Global
<a name="csharp-package-cli"></a>

La CLI de .NET y la extensión .NET Lambda Global Tools (`Amazon.Lambda.Tools`) ofrecen una forma multiplataforma para crear aplicaciones Lambda basadas en .NET, empaquetarlas e implementarlas en Lambda. En esta sección, aprenderá a crear nuevos proyectos .NET de Lambda mediante la CLI de .NET y las plantillas de Amazon Lambda, y a empaquetarlos e implementarlos mediante `Amazon.Lambda.Tools`

**Topics**
+ [

## Requisitos previos
](#csharp-package-cli-prerequisites)
+ [

## Creación de proyectos .NET mediante la CLI de .NET
](#csharp-package-cli-create)
+ [

## Implementación de proyectos.NET mediante la CLI de .NET
](#csharp-package-cli-deploy)
+ [

## Uso de capas de Lambda con la CLI de .NET
](#csharp-layers)

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

**SDK para .NET 8**  
Si aún no lo ha hecho, instale el SDK y el tiempo de ejecución de [.NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0).

**AWS Plantillas de proyecto .NET Amazon.Lambda.Templates**  
Para generar el código de la función de Lambda, utilice el paquete NuGet [https://www.nuget.org/packages/Amazon.Lambda.Templates](https://www.nuget.org/packages/Amazon.Lambda.Templates). Para instalar este paquete de plantillas, ejecute el siguiente comando:  

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

**AWS Herramientas globales para la CLI de .NET Amazon.Lambda.Tools**  
Para crear sus funciones de Lambda, utilice la [extensión de herramientas globales de .NET](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/) [https://www.nuget.org/packages/Amazon.Lambda.Tools](https://www.nuget.org/packages/Amazon.Lambda.Tools). Ejecute el siguiente comando para instalar Amazon.Lambda.Tools:  

```
dotnet tool install -g Amazon.Lambda.Tools
```
Para obtener más información sobre la Amazon.Lambda.Tools de la extensión de la CLI de .NET, consulte el repositorio en GitHub [ Extensiones de AWS para la CLI de .NET](https://github.com/aws/aws-extensions-for-dotnet-cli).

## Creación de proyectos .NET mediante la CLI de .NET
<a name="csharp-package-cli-create"></a>

En la CLI de .NET se usa el comando `dotnet new` para crear proyectos .NET desde la línea de comando. Lambda ofrece plantillas adicionales mediante el paquete [https://www.nuget.org/packages/Amazon.Lambda.Templates](https://www.nuget.org/packages/Amazon.Lambda.Templates) NuGet.

Tras la instalación de este paquete, ejecute el siguiente comando para ver una lista de las plantillas disponibles.

```
dotnet new list
```

Para examinar los detalles acerca de una plantilla, utilice la opción `help`. Por ejemplo, para ver los detalles de la plantilla `lambda.EmptyFunction`, ejecute el siguiente comando.

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

Para crear una plantilla básica para una función de Lambda .NET, utilice la plantilla `lambda.EmptyFunction`. Esto crea una función sencilla que toma una cadena como entrada y la convierte a mayúsculas mediante el método `ToUpper`. Esta plantilla es compatible con las siguientes opciones: 
+ `--name`: el nombre de la función.
+ `--region`: la región AWS para crear la función dentro.
+ `--profile`: el nombre de un perfil en su archivo de credenciales de AWS SDK para .NET. Para obtener más información sobre los perfiles de credenciales en .NET, consulte [Configurar credenciales AWS](https://docs.aws.amazon.com/sdk-for-net/v3/developer-guide/net-dg-config-creds.html) en *SDK AWS para Guía para desarrolladores de .NET*.

En este ejemplo, creamos una nueva función vacía llamada `myDotnetFunction` con el perfil y la configuración Región de AWS predeterminados:

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

Este comando crea los siguientes archivos y directorios en el directorio de su proyecto.

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

En el directorio `src/myDotnetFunction`, examine los archivos siguientes:
+ **aws-lambda-tools-defaults.json**: aquí se especifican las opciones de línea de comando al implementar su función de Lambda. Por ejemplo:

  ```
    "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**: el código de la función de controlador de Lambda. Es una plantilla de C\$1 que incluye la biblioteca `Amazon.Lambda.Core` predeterminada y un atributo `LambdaSerializer` predeterminado. Para obtener más información acerca de las opciones y los requisitos de serialización, consulte [Serialización en C\$1 de las funciones de Lambda](csharp-handler.md#csharp-handler-serializer). También incluye una función de muestra que puede editar para aplicar el código de su función de Lambda.

  ```
  using Amazon.Lambda.Core;
  
  // Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
  [assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
  
  namespace myDotnetFunction;
  
  public class Function
  {
  
      /// <summary>
      /// A simple function that takes a string and does a ToUpper
      /// </summary≫
      /// <param name="input"></param>
      /// <param name="context"></param>
      /// <returns></returns>
      public string FunctionHandler(string input, ILambdaContext context)
      {
          return input.ToUpper();
      }
  }
  ```
+ **myDotnetFunction.csproj**: un archivo [MSBuild](https://msdn.microsoft.com/en-us/library/dd393574.aspx) que enumera los archivos y ensamblados que componen la aplicación.

  ```
  <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**: use este archivo para documentar su función de Lambda.

En el directorio `myfunction/test`, examine los archivos siguientes:
+ **myDotnetFunction.Tests.csproj**: como se ha indicado con anterioridad, este es un archivo [MSBuild](https://msdn.microsoft.com/en-us/library/dd393574.aspx) que enumera los archivos y los ensamblados que componen el proyecto de prueba. Tenga en cuenta que también incluye la biblioteca `Amazon.Lambda.Core`, de modo que puede integrar a la perfección cualquier plantilla de Lambda necesaria para probar la función.

  ```
  <Project Sdk="Microsoft.NET.Sdk">
     ... 
  
      <PackageReference Include="Amazon.Lambda.Core" Version="2.2.0 " />
     ...
  ```
+ **FunctionTest.cs**: el mismo archivo de plantilla de código C\$1 que se incluye en el directorio `src`. Edite este archivo para reflejar el código de producto de su función y probarlo antes de cargar su función de Lambda en un entorno de producción.

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

## Implementación de proyectos.NET mediante la CLI de .NET
<a name="csharp-package-cli-deploy"></a>

Para crear su paquete de implementación e implementarlo en Lambda, utilice las herramientas de CLI `Amazon.Lambda.Tools`. Para implementar la función a partir de los archivos que creó en los pasos anteriores, primero navegue hasta la carpeta que contiene el archivo `.csproj` de la función.

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

Para implementar el código en Lambda como un paquete de implementación .zip, ejecute el siguiente comando. Elija su propio nombre de función.

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

Durante la implementación, el asistente le pide que seleccione un [Definición de permisos de funciones de Lambda con un rol de ejecución](lambda-intro-execution-role.md). Para este ejemplo, seleccione `lambda_basic_role`.

Una vez implementada la función, puede probarla en la nube con el comando `dotnet lambda invoke-function`. Para el código de ejemplo de la plantilla `lambda.EmptyFunction`, puede probar su función pasando una cadena mediante la opción `--payload`.

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

Si la función se ha implementado correctamente, debería ver un resultado similar al siguiente.

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

## Uso de capas de Lambda con la CLI de .NET
<a name="csharp-layers"></a>

**nota**  
Si bien es posible utilizar [capas](chapter-layers.md) con funciones en .NET, se recomienda que no lo haga. Las funciones en .NET que utilizan capas cargan de forma manual los ensamblajes compartidos en la memoria durante la fase de `Init`, lo que puede aumentar los tiempos de arranque en frío. En su lugar, incluya todo el código compartido en el momento de la compilación para aprovechar las optimizaciones integradas en el compilador de .NET.

La CLI de .NET admite comandos que lo ayudan a publicar capas e implementar funciones de C\$1 que consumen capas. Para publicar una capa en un bucket de Amazon S3 específico, ejecute el siguiente comando en el mismo directorio que su archivo `.csproj`:

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

Luego, cuando implemente la función mediante la CLI de .NET, especifique el ARN de la capa que consumirá en el siguiente comando:

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

Para conocer un ejemplo completo de una función “Hola, mundo”, consulte la muestra [blank-csharp-with-layer](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-csharp-with-layer).

# Implemente las funciones de Lambda C\$1 utilizando AWS SAM
<a name="csharp-package-sam"></a>

AWS Serverless Application Model (AWS SAM) es un conjunto de herramientas que ayuda a agilizar el proceso de creación y ejecución de aplicaciones sin servidor en AWS. Defina los recursos de su aplicación en una plantilla YAML o JSON y utilice la interfaz de la línea de comandos de AWS SAM (AWS SAM CLI) para crear, empaquetar e implementar sus aplicaciones. Al crear una función de Lambda a partir de una plantilla de AWS SAM, AWS SAM crea automáticamente un paquete de implementación .zip o una imagen de contenedor con el código de la función y las dependencias que especifique. Después, AWS SAM implementa la función mediante una [pila CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacks.html).zip Para obtener más información sobre el uso de AWS SAM para crear e implementar funciones de Lambda, consulte [Introducción a AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started.html) en la *Guía para desarrolladores de AWS Serverless Application Model*.

Los siguientes pasos muestran cómo descargar, crear e implementar una aplicación Hello World .NET de muestra mediante AWS SAM. Esta aplicación de muestra utiliza una función de Lambda y un punto de conexión de Amazon API Gateway para implementar un backend de API básico. Cuando envía una solicitud GET de HTTP a su punto de conexión de API Gateway, la última invoca la función de Lambda. La función devuelve un mensaje “Hello world”, junto con la dirección IP de la instancia de la función de Lambda que procesa la solicitud.

Al crear e implementar la aplicación mediante AWS SAM, entre bastidores, la CLI AWS SAM utiliza el comando `dotnet lambda package` para empaquetar los grupos de códigos de las funciones de Lambda individuales.

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

**SDK para .NET 8**  
Instale el SDK y el tiempo de ejecución de [.NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0).

**Versión 1.39 o posterior de la CLI de AWS SAM**  
Para instalar la última versión de la CLI de AWS SAM, consulte [Instalación de la CLI de AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html).

## Implementar una aplicación de ejemplo de AWS SAM
<a name="csharp-package-sam-deploy"></a>

1. Inicialice la aplicación con la plantilla Hello world de .NET con el siguiente comando.

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

   Este comando crea los siguientes archivos y directorios en el directorio de su proyecto.

   ```
   └── 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. Navegue hasta el directorio que contiene el `template.yaml file`. Este archivo es una plantilla que define los recursos AWS de la aplicación, incluida la función de Lambda y una API de API Gateway.

   ```
   cd sam-app
   ```

1. Para crear la fuente de la aplicación, ejecute el siguiente comando.

   ```
   sam build
   ```

1. Para implementar la aplicación en AWS, ejecute el siguiente comando.

   ```
   sam deploy --guided
   ```

   Este comando empaqueta e implementa la aplicación con la siguiente serie de solicitudes. Para aceptar las opciones predeterminadas, pulse Enter.
**nota**  
Puede que **HelloWorldFunction no tenga definida la autorización, ¿está bien?** Asegúrese de ingresar `y`.
   + **Nombre de la pila**: el nombre de la pila para la implementación en CloudFormation. Este nombre debe ser exclusivo para Cuenta de AWS y Región de AWS.
   + **Región de AWS**: El Región de AWS en el que desea implementar su aplicación.
   + **Confirme los cambios antes de la implementación**: seleccione “Sí” para revisar manualmente cualquier conjunto de cambios antes de que AWS SAM implemente los cambios en la aplicación. Si selecciona “No”, la CLI AWS SAM implementa automáticamente los cambios en las aplicaciones.
   + **Permitir la creación de roles de IAM en la CLI de SAM**: muchas plantillas AWS SAM, incluida la de Hello world en este ejemplo, crean roles (de IAM) AWS Identity and Access Management para dar permiso a las funciones de Lambda para acceder a otras Servicios de AWS. Seleccione “Sí” para conceder permiso para implementar una pila CloudFormation que cree o modifique los roles de IAM.
   + **Desactivar la reversión**: de forma predeterminada, si AWS SAM encuentra un error durante la creación o la implementación de la pila, la devuelve a la versión anterior. Seleccione “No” para aceptar este valor predeterminado.
   + Puede que **HelloWorldFunction no tenga definida la autorización, ¿está bien?**: Ingrese `y`.
   + **Guardar los argumentos en samconfig.toml**: seleccione “Sí” para guardar las opciones de configuración. En el futuro, podrá volver a ejecutar `sam deploy` sin parámetros para implementar cambios en la aplicación.

1. Una vez finalizada la implementación de la aplicación, la CLI devuelve el nombre de recurso de Amazon (ARN) de la función de Lambda de Hello World y el rol de IAM creado para la misma. También muestra el punto de conexión de la API de API Gateway. Para probar la aplicación, abra el punto de conexión en un navegador. Verá una respuesta parecida a la siguiente.

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

1. Use el siguiente comando para eliminar los recursos. Tenga en cuenta que el punto de conexión de la API que ha creado es un punto de conexión público al que se puede acceder a través de Internet. Se recomienda eliminar este punto de conexión después de las pruebas.

   ```
   sam delete
   ```

## Pasos a seguir a continuación
<a name="csharp-package-sam-next"></a>

Para obtener más información sobre AWS SAM para crear e implementar funciones de Lambda mediante .NET, consulte los siguientes recursos:
+ La [guía para desarrolladores de *AWS Serverless Application Model (AWS SAM)*](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html)
+ [Creación de aplicaciones .NET sin servidor con la CLI AWS Lambda de SAM](https://aws.amazon.com/blogs/dotnet/building-serverless-net-applications-with-aws-lambda-and-the-sam-cli/)

# Implemente las funciones de Lambda C\$1 utilizando AWS CDK
<a name="csharp-package-cdk"></a>

AWS Cloud Development Kit (AWS CDK) es un marco de desarrollo de software de código abierto para definir la infraestructura de nube como código con marcos y lenguajes de programación modernos, como .NET. Los proyectos AWS CDK se ejecutan para generar plantillas CloudFormation que luego se utilizan para implementar el código.

Para crear e implementar un ejemplo de aplicación Hello world .NET mediante AWS CDK, siga las instrucciones de las siguientes secciones. La aplicación de ejemplo implementa un backend de API básico que consta de un punto de conexión API Gateway y una función de Lambda. Cuando se envía una solicitud HTTP GET al punto de conexión, API Gateway invoca la función de Lambda. La función devuelve un mensaje “Hello world”, junto con la dirección IP de la instancia Lambda que procesa la solicitud.

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

**SDK para .NET 8**  
Instale el SDK y el tiempo de ejecución de [.NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0).

**Versión 2 de la AWS CDK**  
Para obtener información sobre cómo instalar la última versión de AWS CDK consulte [Introducción a la AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html) en la *Guía para desarrolladores de AWS Cloud Development Kit (AWS CDK) versión 2.*.

## Implementar una aplicación de ejemplo de AWS CDK
<a name="csharp-package-cdk-deploy"></a>

1. Cree un directorio de proyectos para la aplicación de ejemplo y navegue hasta él.

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

1. Inicialice una nueva aplicación AWS CDK mediante la ejecución del siguiente comando.

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

   El comando crea los siguientes archivos y directorios en el directorio del proyecto

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

1. Abra el directorio `src` y cree una nueva función de Lambda mediante la CLI de .NET. Esta es la función que implementará mediante AWS CDK. En este ejemplo, se crea una función Hello world denominada `HelloWorldLambda` mediante la plantilla `lambda.EmptyFunction`.

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

   Después de este paso, la estructura dentro del directorio de proyectos debería tener el siguiente aspecto.

   ```
   ├── 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. Abra el archivo `HelloWorldStack.cs` del directorio `src/HelloWorld`. Reemplace el contenido del archivo por lo siguiente.

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

   Este es el código para compilar y empaquetar el código de la aplicación, así como la definición de la propia función de Lambda. El objeto `BundlingOptions` permite crear un archivo zip junto con un conjunto de comandos que se utilizan para generar el contenido del archivo zip. En este caso, el comando `dotnet lambda package` se usa para compilar y generar el archivo zip.

1. Para implementar la aplicación, ejecute el siguiente comando.

   ```
   cdk deploy
   ```

1. Invoque la función de Lambda implementada mediante la CLI de .NET Lambda.

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

1. Al acabar las prueba, a menos que desee retener los recursos que creó, puede eliminarlos. Use el siguiente comando para eliminar los recursos.

   ```
   cdk destroy
   ```

## Pasos a seguir a continuación
<a name="csharp-package-cdk-next"></a>

Para obtener más información sobre AWS CDK para crear e implementar funciones de Lambda mediante .NET, consulte los siguientes recursos:
+ [Utilización del CDK AWS en C\$1](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-csharp.html)
+ [Cree, empaquete y publique funciones de Lambda C\$1 de .NET con el CDK AWS](https://aws.amazon.com/blogs/modernizing-with-aws/build-package-publish-dotnet-csharp-lambda-functions-aws-cdk/)

# Implementación de aplicaciones ASP .NET
<a name="csharp-package-asp"></a>

Además de alojar funciones basadas en eventos, también puede utilizar .NET con Lambda para alojar aplicaciones ASP .NET ligeras. Puede crear e implementar aplicaciones ASP .NET mediante el paquete NuGet `Amazon.Lambda.AspNetCoreServer`. En esta sección, aprenderá a implementar una API web de ASP .NET en Lambda mediante las herramientas de CLI de Lambda .NET.

**Topics**
+ [

## Requisitos previos
](#csharp-package-asp-prerequisites)
+ [

## Implementación de una API web de ASP.NET en Lambda
](#csharp-package-asp-deploy-api)
+ [

## Implementación de API mínimas de ASP .NET en Lambda
](#csharp-package-asp-deploy-minimal)

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

**SDK para .NET 8**  
Instale el SDK de [.NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) y el tiempo de ejecución de ASP .NET Core.

**Amazon.Lambda.Tools**  
Para crear sus funciones de Lambda, utilice la [extensión de herramientas globales de .NET](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/) [https://www.nuget.org/packages/Amazon.Lambda.Tools](https://www.nuget.org/packages/Amazon.Lambda.Tools). Ejecute el siguiente comando para instalar Amazon.Lambda.Tools:  

```
dotnet tool install -g Amazon.Lambda.Tools
```
Para obtener más información sobre la Amazon.Lambda.Tools de la extensión de la CLI de .NET, consulte el repositorio en GitHub [ Extensiones de AWS para la CLI de .NET](https://github.com/aws/aws-extensions-for-dotnet-cli).

**Amazon.Lambda.Templates**  
Para generar el código de la función de Lambda, utilice el paquete NuGet [https://www.nuget.org/packages/Amazon.Lambda.Templates](https://www.nuget.org/packages/Amazon.Lambda.Templates). Para instalar este paquete de plantillas, ejecute el siguiente comando:  

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

## Implementación de una API web de ASP.NET en Lambda
<a name="csharp-package-asp-deploy-api"></a>

Para implementar una API web mediante ASP .NET, puede usar las plantillas .NET Lambda para crear un nuevo proyecto de API web. Utilice el siguiente comando para inicializar un nuevo proyecto de API web de ASP .NET. En el comando de ejemplo, asignamos un nombre al proyecto `AspNetOnLambda`.

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

Este comando crea los siguientes archivos y directorios en el directorio de su proyecto.

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

Cuando Lambda invoca la función, el punto de entrada que utiliza es el archivo `LambdaEntryPoint.cs`. El archivo creado por la plantilla Lambda de .NET contiene el siguiente código.

```
namespace AspNetOnLambda;

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

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

El punto de entrada utilizado por Lambda debe heredar de una de las tres clases base del paquete `Amazon.Lambda.AspNetCoreServer`. Estas tres clases base son:
+ `APIGatewayProxyFunction`
+ `APIGatewayHttpApiV2ProxyFunction`
+ `ApplicationLoadBalancerFunction`

La clase predeterminada que se utiliza al crear el archivo `LambdaEntryPoint.cs` con la plantilla .NET Lambda proporcionada es `APIGatewayProxyFunction`. La clase base que utilice en la función depende de la capa de API situada delante de la función de Lambda.

Cada una de las tres clases base contiene un método público denominado `FunctionHandlerAsync`. El nombre de este método formará parte de la [cadena de controladores](csharp-handler.md#csharp-class-library-handlers) que Lambda utiliza para invocar la función. El método `FunctionHandlerAsync` transforma la carga útil del evento entrante en el formato de ASP .NET correcto y la respuesta de ASP .NET en una carga útil de respuesta de Lambda. Para el proyecto `AspNetOnLambda` de ejemplo que se muestra, la cadena del controlador sería la siguiente.

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

Para implementar la API en Lambda, ejecute los siguientes comandos para navegar al directorio que contiene el archivo de código fuente e implementar la función mediante CloudFormation.

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

**sugerencia**  
Al implementar una API mediante el comando `dotnet lambda deploy-serverless`, CloudFormation asigna un nombre a la función de Lambda según el nombre de pila que especifique durante la implementación. Para asignar un nombre personalizado a la función de Lambda, edite el archivo `serverless.template` para agregar una propiedad `FunctionName` al recurso `AWS::Serverless::Function`. Para obtener más información, consulte [Tipo de nombre](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-name.html) en la *Guía del usuario de CloudFormation*.

## Implementación de API mínimas de ASP .NET en Lambda
<a name="csharp-package-asp-deploy-minimal"></a>

Para implementar una API mínima de ASP .NET en Lambda, puede usar las plantillas Lambda .NET para crear un nuevo proyecto de API mínima. Use el siguiente comando para inicializar un nuevo proyecto de API mínima. En este ejemplo, usamos el nombre de proyecto `MinimalApiOnLambda`.

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

El comando crea los siguientes archivos y directorios en el directorio de su proyecto.

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

El archivo `Program.cs` contiene la salida siguiente.

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

Para configurar su API mínima para que se ejecute en Lambda, es posible que necesite editar este código para que las solicitudes y respuestas entre Lambda y ASP .NET Core se traduzcan correctamente. De forma predeterminada, la función está configurada para una fuente de eventos de la API de REST. En el caso de una API HTTP o un equilibrador de carga de aplicación, sustituya `(LambdaEventSource.RestApi)` por una de las siguientes opciones:
+ `(LambdaEventSource.HttpAPi)`
+ `(LambdaEventSource.ApplicationLoadBalancer)`

Para implementar su API mínima en Lambda, ejecute los siguientes comandos para navegar al directorio que contiene el archivo de código fuente e implementar la función mediante CloudFormation.

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

# Uso de capas para funciones de Lambda .NET
<a name="dotnet-layers"></a>

No recomendamos usar [capas](chapter-layers.md) para administrar las dependencias de las funciones de Lambda escritas en .NET. Como .NET es un lenguaje compilado, las funciones aún tienen que cargar de forma manual los ensamblajes compartidos en la memoria durante la fase de [inicio](lambda-runtime-environment.md#runtimes-lifecycle-ib), lo que puede aumentar los tiempos de arranque en frío. El uso de capas no solo complica el proceso de implementación, sino que también impide que se aprovechen las optimizaciones del compilador integrado.

Para usar dependencias externas con los controladores de .NET, inclúyalas directamente en el paquete de implementación en el momento de la compilación. Al hacerlo, se simplifica el proceso de implementación y también se aprovechan las optimizaciones del compilador de .NET integrado. Para ver un ejemplo de cómo importar y usar dependencias como los paquetes NuGet en su función, consulte [Definir el controlador de funciones de Lambda en C\$1](csharp-handler.md).

# Implementar funciones de Lambda .NET con imágenes de contenedor
<a name="csharp-image"></a>

Hay tres formas de crear una imagen de contenedor para una función de Lambda en .NET:
+ [Uso de una imagen base de AWS para .NET](#csharp-image-instructions)

  Las [imágenes base de AWS](images-create.md#runtimes-images-lp) vienen precargadas con un tiempo de ejecución de lenguaje, un cliente de interfaz de tiempo de ejecución para administrar la interacción entre Lambda y el código de la función y un emulador de interfaz de tiempo de ejecución para realizar pruebas a nivel local.
+ [Uso de una imagen base exclusiva del sistema operativo de AWS](images-create.md#runtimes-images-provided)

  [Las imágenes base exclusivas del sistema operativo de AWS](https://gallery.ecr.aws/lambda/provided)contienen una distribución de Amazon Linux y el [emulador de interfaz de tiempo de ejecución](https://github.com/aws/aws-lambda-runtime-interface-emulator/). Por lo general, estas imágenes se utilizan para crear imágenes contenedoras para lenguajes compilados, como [Go](go-image.md#go-image-provided) y [Rust](lambda-rust.md), y para un lenguaje o versión de un lenguaje para los que Lambda no proporciona una imagen base, como Node.js 19. También puede usar imágenes base exclusivas del sistema operativo para implementar un [tiempo de ejecución personalizado](runtimes-custom.md). Para que la imagen sea compatible con Lambda, debe incluir el [cliente de interfaz de tiempo de ejecución para .NET](#csharp-image-clients) en la imagen.
+ [Uso de una imagen base que no sea de AWS](#csharp-image-clients)

  Puede utilizar una imagen base alternativa de otro registro de contenedores, como Alpine Linux o Debian. También puede utilizar una imagen personalizada creada por su organización. Para que la imagen sea compatible con Lambda, debe incluir el [cliente de interfaz de tiempo de ejecución para .NET](#csharp-image-clients) en la imagen.

**sugerencia**  
Para reducir el tiempo que tardan las funciones de contenedor de Lambda en activarse, consulte [Uso de compilaciones de varias fases](https://docs.docker.com/build/building/multi-stage/) en la documentación de Docker. Para compilar imágenes de contenedores eficientes, siga [Prácticas recomendadas para escribir Dockerfiles](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/).

En esta página, se explica cómo compilar, probar e implementar imágenes de contenedor para Lambda.

**Topics**
+ [

## AWS imágenes base para .NET
](#csharp-image-base)
+ [

## Uso de una imagen base de AWS para .NET
](#csharp-image-instructions)
+ [

## Uso de una imagen base alternativa con el cliente de interfaz de tiempo de ejecución
](#csharp-image-clients)

## AWS imágenes base para .NET
<a name="csharp-image-base"></a>

AWS proporciona las siguientes imágenes base para .NET:


| Etiquetas | Tiempo de ejecución | Sistema operativo | Dockerfile | Obsolescencia | 
| --- | --- | --- | --- | --- | 
| 10 | .NET 10 | Amazon Linux 2023 | [Dockerfile para .NET 10 en GitHub](https://github.com/aws/aws-lambda-base-images/blob/dotnet10/Dockerfile.dotnet10) |   14 de noviembre de 2028   | 
| 9 | .NET 9 | Amazon Linux 2023 | [Dockerfile para .NET 9 en GitHub](https://github.com/aws/aws-lambda-base-images/blob/dotnet9/Dockerfile.dotnet9) |   10 de noviembre de 2026   | 
| 8 | .NET 8 | Amazon Linux 2023 | [Dockerfile para .NET 8 en GitHub](https://github.com/aws/aws-lambda-base-images/blob/dotnet8/Dockerfile.dotnet8) |   10 de noviembre de 2026   | 

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

## Uso de una imagen base de AWS para .NET
<a name="csharp-image-instructions"></a>

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

Para completar los pasos de esta sección, debe disponer de lo siguiente:
+ [SDK de .NET](https://dotnet.microsoft.com/download): en los siguientes pasos se utiliza la imagen base de .NET 8. Asegúrese de que su versión de .NET coincida con la versión de la [imagen base](https://gallery.ecr.aws/lambda/dotnet) que especifique en su Dockerfile.
+ [Docker](https://docs.docker.com/get-docker) (versión mínima 25.0.0)
+ El [complemento buildx](https://github.com/docker/buildx/blob/master/README.md) de Docker.

### Creación e implementación de una imagen con una imagen base
<a name="dotnet-image-create"></a>

En los siguientes pasos, utilizará [Amazon.Lambda.Templates](https://github.com/aws/aws-lambda-dotnet#dotnet-cli-templates) y [Amazon.Lambda.Tools](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools) para crear un proyecto .NET. A continuación, creará una imagen de Docker, cargará la imagen a Amazon ECR y la implementará en una función de Lambda.

1. Instale el paquete NuGet de [Amazon.Lambda.Templates](https://github.com/aws/aws-lambda-dotnet#dotnet-cli-templates).

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

1. Cree un proyecto de .NET con la plantilla `lambda.image.EmptyFunction`.

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

   Los archivos de proyecto se almacenan en el directorio `MyFunction/src/MyFunction`:
   + **aws-lambda-tools-defaults.json**: especifica las opciones de línea de comando para implementar su función de Lambda.
   + **Function.cs**: el código de la función de controlador de Lambda. Es una plantilla de C\$1 que incluye la biblioteca `Amazon.Lambda.Core` predeterminada y un atributo `LambdaSerializer` predeterminado. Para obtener más información acerca de las opciones y los requisitos de serialización, consulte [Serialización en C\$1 de las funciones de Lambda](csharp-handler.md#csharp-handler-serializer). Puede utilizar el código proporcionado para realizar pruebas o sustituirlo por su propio código.
   + **MyFunction.csproj**: un [archivo de proyecto](https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview#project-files) .NET que enumera los archivos y ensamblados que componen la aplicación.
   + **Dockerfile**: puede usar el Dockerfile proporcionado para realizar pruebas o sustituirlo por el suyo propio. Si usa el suyo propio, asegúrese de que se cumpla lo siguiente:
     + Establezca la propiedad `FROM` en el [URI de la imagen base](https://gallery.ecr.aws/lambda/dotnet). Tanto la imagen base como el `TargetFramework` en el archivo `MyFunction.csproj` deben usar la misma versión .NET. Por ejemplo, para utilizar .NET 9:
       + Dockerfile: `FROM public.ecr.aws/lambda/dotnet:9`
       + MyFunction.csproj: `<TargetFramework>net9.0</TargetFramework>`
     + Establezca el argumento `CMD` para el controlador de la función de Lambda. Esto debe coincidir con `image-command` en `aws-lambda-tools-defaults.json`.

1. Instale la [herramienta global .NET](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/) de Amazon.Lambda.Tools.

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

   Si ya se ha instalado Amazon.Lambda.Tools, asegúrese de que posee la versión más reciente.

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

1. Cambie el directorio a `MyFunction/src/MyFunction` si aún no se encuentra allí.

   ```
   cd src/MyFunction
   ```

1. Utilice Amazon.Lambda.Tools para crear la imagen de Docker, subirla a un nuevo repositorio de Amazon ECR e implementar la función de Lambda.

   En `--function-role`, especifique el nombre del rol (no el nombre de recurso de Amazon (ARN)) del [rol de ejecución](lambda-intro-execution-role.md) de la función. Por ejemplo, `lambda-role`.

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

   Para obtener más información acerca de la herramienta global de .NET de Amazon.Lambda.Tools, consulte el repositorio [Extensiones de AWS para la CLI de .NET](https://github.com/aws/aws-extensions-for-dotnet-cli) en GitHub.

1. Invoque la función.

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

   Si todo es correcto, verá una respuesta similar a la siguiente:

   ```
   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. Elimine la función de Lambda.

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

## Uso de una imagen base alternativa con el cliente de interfaz de tiempo de ejecución
<a name="csharp-image-clients"></a>

Si usa una [imagen base exclusiva del sistema operativo](images-create.md#runtimes-images-provided) o una imagen base alternativa, debe incluir el cliente de interfaz de tiempo de ejecución en su imagen. El cliente de interfaz de tiempo de ejecución extiende el [API de tiempo de ejecución](runtimes-api.md), que administra la interacción entre Lambda y el código de la función.

En el siguiente ejemplo, se muestra cómo crear una imagen de contenedor para .NET con una imagen base que no es de AWS y cómo agregar el [paquete 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), que es el cliente de interfaz de tiempo de ejecución de Lambda para .NET. El Dockerfile de ejemplo utiliza la imagen base de .NET 8 para Microsoft.

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

Para completar los pasos de esta sección, debe disponer de lo siguiente:
+ [SDK de .NET ](https://dotnet.microsoft.com/download): en los siguientes pasos, se utiliza una imagen base de .NET 9. Asegúrese de que su versión de .NET coincida con la versión de la imagen base que especifique en su Dockerfile.
+ [Docker](https://docs.docker.com/get-docker) (versión mínima 25.0.0)
+ El [complemento buildx](https://github.com/docker/buildx/blob/master/README.md) de Docker.

### Creación e implementación de una imagen con una imagen base alternativa
<a name="dotnet-alt-create"></a>

1. Instale el paquete NuGet de [Amazon.Lambda.Templates](https://github.com/aws/aws-lambda-dotnet#dotnet-cli-templates).

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

1. Cree un proyecto de .NET con la plantilla `lambda.CustomRuntimeFunction`. Esta plantilla incluye el paquete [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).

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

1. Vaya al directorio `MyFunction/src/MyFunction`. Aquí es donde se almacenan los archivos del proyecto. Examine los siguientes archivos:
   + **aws-lambda-tools-defaults.json**: en este archivo se especifican las opciones de la línea de comandos al implementar su función de Lambda.
   + **Function.cs**: el código contiene una clase con un método `Main` que inicializa la biblioteca `Amazon.Lambda.RuntimeSupport` como el arranque. El método `Main` es el punto de entrada para el proceso de la función. El método `Main` empaqueta el controlador de funciones en un contenedor con el que puede funcionar el arranque. Para obtener más información, consulte [Uso de Amazon.Lambda.RuntimeSupport como biblioteca de clases](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.RuntimeSupport/README.md#using-amazonlambdaruntimesupport-as-a-class-library) en el repositorio de GitHub.
   + **MyFunction.csproj**: un [archivo de proyecto](https://learn.microsoft.com/en-us/dotnet/core/project-sdk/overview#project-files) de .NET que enumera los archivos y ensamblados que componen la aplicación.
   + **Readme.md**: este archivo contiene más información sobre la función de Lambda de muestra.

1. Abra el archivo `aws-lambda-tools-defaults.json` y agregue las siguientes líneas:

   ```
     "package-type": "image",
     "docker-host-build-output-dir": "./bin/Release/lambda-publish"
   ```
   + **package-type**: define el paquete de despliegue como una imagen de contenedor.
   + **docker-host-build-output-dir**: establece el directorio de salida para el proceso de compilación.  
**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. Cree un Dockerfile en el directorio `MyFunction/src/MyFunction`. El siguiente Dockerfile de ejemplo usa una imagen base de .NET para Microsoft en lugar de una [imagen base de AWS](#csharp-image-base).
   + Establezca la propiedad `FROM` como el identificador de la imagen base. Tanto la imagen base como el `TargetFramework` en el archivo `MyFunction.csproj` deben usar la misma versión .NET.
   + Utilice el comando `COPY` para copiar la función en el directorio `/var/task`.
   + Configure `ENTRYPOINT` como el módulo que desea que el contenedor de Docker ejecute cuando se inicie. En este caso, el módulo es el arranque, que inicializa la biblioteca `Amazon.Lambda.RuntimeSupport`.

   Tenga en cuenta que el Dockerfile de ejemplo no incluye una [instrucción USER](https://docs.docker.com/reference/dockerfile/#user). Al implementar una imagen de contenedor en Lambda, Lambda define automáticamente un usuario predeterminado de Linux con permisos de privilegio mínimo. Esto es diferente del comportamiento estándar de Docker, que utiliza de forma predeterminada el usuario `root` cuando no se proporciona ninguna instrucción `USER`.  
**Example Dockerfile**  

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

1. Instale la [extensión de herramientas globales de .NET](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/) de Amazon.Lambda.Tools.

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

   Si ya se ha instalado Amazon.Lambda.Tools, asegúrese de que posee la versión más reciente.

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

1. Utilice Amazon.Lambda.Tools para crear la imagen de Docker, subirla a un nuevo repositorio de Amazon ECR e implementar la función de Lambda.

   En `--function-role`, especifique el nombre del rol (no el nombre de recurso de Amazon (ARN)) del [rol de ejecución](lambda-intro-execution-role.md) de la función. Por ejemplo, `lambda-role`.

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

   Para obtener más información acerca de la extensión CLI de la herramienta global de .NET de Amazon Lambda, consulte el repositorio [Extensiones de AWS para la CLI de .NET](https://github.com/aws/aws-extensions-for-dotnet-cli) en GitHub.

1. Invoque la función.

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

   Si todo es correcto, verá lo siguiente:

   ```
   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. Elimine la función de Lambda.

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

# Compilar el código de una función de Lambda .NET en un formato de tiempo de ejecución nativo
<a name="dotnet-native-aot"></a>

.NET 8 admite la compilación nativa anticipada (AOT). Con el enfoque nativo anticipado, puede compilar el código de la función de Lambda en un formato de tiempo de ejecución nativo, lo que elimina la necesidad de compilar código .NET en el tiempo de ejecución. La compilación nativa anticipada puede reducir el tiempo de inicio en frío de las funciones de Lambda que crea con .NET. Para obtener más información, consulte [Introducción al tiempo de ejecución de .NET 8 para AWS Lambda](https://aws.amazon.com/blogs/compute/introducing-the-net-8-runtime-for-aws-lambda/) en el Blog de informática de AWS.

**Topics**
+ [

## Tiempo de ejecución de Lambda
](#dotnet-native-aot-runtime)
+ [

## Requisitos previos
](#dotnet-native-aot-prerequisites)
+ [

## Introducción
](#dotnet-native-aot-getting-started)
+ [

## Serialización
](#dotnet-native-aot-serialization)
+ [

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

## Resolución de problemas
](#dotnet-native-aot-troubleshooting)

## Tiempo de ejecución de Lambda
<a name="dotnet-native-aot-runtime"></a>

Utilice el tiempo de ejecución administrado de .NET 8 en Lambda para implementar una función de Lambda que se cree con la compilación nativa anticipada (AOT). Este tiempo de ejecución es compatible con las arquitecturas x86\$164 y arm64.

Cuando implementa una función de Lambda en .NET sin utilizar AOT, la aplicación primero se compila en código de lenguaje intermedio (IL). Durante el tiempo de ejecución, la compilación en tiempo de ejecución (JIT) de Lambda toma el código IL y lo compila en código de máquina según sea necesario. Con una función de Lambda que se compila con antelación mediante una AOT nativa, el código se compila en código de máquina al implementar la función. Por lo tanto, no se depende del tiempo de ejecución de .NET ni del SDK en el tiempo de ejecución de Lambda para compilar el código antes de la ejecución.

Una limitación de AOT implica que el código de la aplicación debe compilarse en un entorno con el mismo sistema operativo Amazon Linux 2023 (AL2023) que utiliza el tiempo de ejecución de .NET 8. La CLI de Lambda .NET proporciona la funcionalidad para compilar la aplicación en un contenedor de Docker mediante una imagen AL2023.

Para evitar posibles problemas de compatibilidad entre arquitecturas, le recomendamos encarecidamente que compile el código en un entorno con la misma arquitectura de procesador que configuró para la función. Para obtener más información sobre las limitaciones de la compilación entre arquitecturas, consulte [Compilación entre arquitecturas](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/cross-compile) en la documentación de Microsoft .NET.

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

**Docker**  
Para utilizar la AOT nativa, el código de la función debe compilarse en un entorno con el mismo sistema operativo AL2023 que el tiempo de ejecución de .NET 8. Los comandos de la CLI de .NET de las siguientes secciones utilizan Docker para desarrollar y crear funciones de Lambda en un entorno AL2023.

**SDK para .NET 8**  
La compilación nativa anticipada es una característica de .NET 8. Debe instalar el [SDK para .NET 8](https://dotnet.microsoft.com/en-us/download/dotnet/8.0) en su máquina de compilación, no solo el tiempo de ejecución.

**Amazon.Lambda.Tools**  
Para crear sus funciones de Lambda, utilice la [extensión de herramientas globales de .NET](https://aws.amazon.com/blogs/developer/net-core-global-tools-for-aws/) [https://www.nuget.org/packages/Amazon.Lambda.Tools](https://www.nuget.org/packages/Amazon.Lambda.Tools). Ejecute el siguiente comando para instalar Amazon.Lambda.Tools:  

```
dotnet tool install -g Amazon.Lambda.Tools
```
Para obtener más información sobre la Amazon.Lambda.Tools de la extensión de la CLI de .NET, consulte el repositorio en GitHub [ Extensiones de AWS para la CLI de .NET](https://github.com/aws/aws-extensions-for-dotnet-cli).

**Amazon.Lambda.Templates**  
Para generar el código de la función de Lambda, utilice el paquete NuGet [https://www.nuget.org/packages/Amazon.Lambda.Templates](https://www.nuget.org/packages/Amazon.Lambda.Templates). Para instalar este paquete de plantillas, ejecute el siguiente comando:  

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

## Introducción
<a name="dotnet-native-aot-getting-started"></a>

Tanto la CLI global de .NET como la AWS Serverless Application Model (AWS SAM) proporcionan plantillas de introducción para crear aplicaciones mediante la AOT nativa. Para crear su primera función de Lambda AOT nativa, lleve a cabo los pasos de las siguientes instrucciones.

**Para inicializar e implementar una función de Lambda nativa compilada en AOT**

1. Inicialice un nuevo proyecto con la plantilla AOT nativa y, a continuación, navegue hasta el directorio que contiene los archivos `.cs` y `.csproj` creados. En este ejemplo, asignamos un nombre a nuestra función `NativeAotSample`.

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

   El archivo `Function.cs` creado por la plantilla AOT nativa contiene el siguiente código de función.

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

   La AOT nativa compila la aplicación en un único binario nativo. El punto de entrada de ese binario es el método `static Main`. Dentro de `static Main`, se inicia el tiempo de ejecución de Lambda y se configura el método `FunctionHandler`. Como parte del arranque del tiempo de ejecución, se configura un serializador generado en la fuente mediante `new SourceGeneratorLambdaJsonSerializer<LambdaFunctionJsonSerializerContext>()`

1. Para implementar la aplicación en Lambda, asegúrese de que Docker se esté ejecutando en su entorno local y ejecute el siguiente comando.

   ```
   dotnet lambda deploy-function
   ```

   Entre bastidores, la CLI global de .NET descarga una imagen de Docker de AL2023 y compila el código de la aplicación dentro de un contenedor en ejecución. El binario compilado se devuelve a su sistema de archivos local antes de implementarlo en Lambda.

1. Pruebe la función al ejecutar el siguiente comando. Reemplace `<FUNCTION_NAME>` por el nombre que eligió para la función en el asistente de implementación.

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

   La respuesta de la CLI incluye detalles de rendimiento para el arranque en frío (duración de la inicialización) y el tiempo total de ejecución de la invocación de la función.

1. Para eliminar los recursos de AWS que creó siguiendo los pasos anteriores, ejecute el siguiente comando. Reemplace `<FUNCTION_NAME>` por el nombre que eligió para la función en el asistente de implementación. Si elimina los recursos de AWS que ya no utiliza, evitará que se facturen gastos innecesarios en su Cuenta de AWS.

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

## Serialización
<a name="dotnet-native-aot-serialization"></a>

Para implementar funciones en Lambda mediante la AOT nativa, el código de la función debe usar la [serialización generada en la fuente](https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/source-generation-modes?pivots=dotnet-8-0). En lugar de utilizar la reflexión en tiempo de ejecución para recopilar los metadatos necesarios para acceder a las propiedades de los objetos con fines de serialización, los generadores de fuentes generan archivos fuente en C\$1 que se compilan al crear la aplicación. Para configurar correctamente el serializador generado en código fuente, asegúrese de incluir todos los objetos de entrada y salida que utilice su función, así como cualquier tipo personalizado. Por ejemplo, una función de Lambda que recibe eventos de una API de REST de API Gateway y devuelve un tipo de `Product` personalizado incluiría un serializador definido de la siguiente manera.

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

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

La AOT nativa recorta el código de la aplicación como parte de la compilación para garantizar que el binario sea lo más pequeño posible. .NET 8 para Lambda proporciona un mejor soporte de reducción de tamaño en comparación con las versiones anteriores de .NET. Se ha añadido compatibilidad con las [bibliotecas de tiempo de ejecución de Lambda](https://github.com/aws/aws-lambda-dotnet/pull/1596), [SDK de .NET de AWS](https://github.com/aws/aws-sdk-net/pulls?q=is%3Apr+trimming), las [anotaciones de Lambda para .NET](https://github.com/aws/aws-lambda-dotnet/pull/1610) y .NET 8.

Estas mejoras ofrecen la posibilidad de eliminar las advertencias de recorte durante el tiempo de compilación, pero .NET nunca será completamente seguro para la reducción. Esto significa que las partes de las bibliotecas en las que se basa su función pueden recortarse como parte del paso de compilación. Para gestionarlo, puede definir `TrimmerRootAssemblies` en su archivo `.csproj`, tal como se muestra en el ejemplo siguiente. 

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

Tenga en cuenta que cuando reciba una advertencia de recorte, es posible que añadir la clase que genera la advertencia a `TrimmerRootAssembly` no resuelva el problema. Una advertencia de recorte indica que la clase está intentando acceder a otra clase que no se puede determinar hasta el tiempo de ejecución. Para evitar errores de tiempo de ejecución, añada esta segunda clase a `TrimmerRootAssembly`.

Para obtener más información sobre la administración de las advertencias de recorte, consulte [Introducción a las advertencias de recorte](https://learn.microsoft.com/en-us/dotnet/core/deploying/trimming/fixing-warnings) en la documentación de Microsoft .NET.

## Resolución de problemas
<a name="dotnet-native-aot-troubleshooting"></a>

**Error: no se admite la compilación nativa entre sistemas operativos.**  
Su versión de la herramienta global de .NET Core Amazon.Lambda.Tools está desactualizada. Actualice la herramienta a la versión más reciente e inténtelo de nuevo.

**Docker: el sistema operativo de imágenes “Linux” no se puede utilizar en esta plataforma.**  
Docker está configurado en su sistema para usar contenedores de Windows. Cambie a contenedores de Linux para ejecutar el entorno de compilación nativa anticipada.

Para obtener más información sobre los errores comunes, consulte el repositorio en GitHub [Enfoque nativo anticipado de AWS para .NET](https://github.com/awslabs/dotnet-nativeaot-labs#common-errors).

# Uso del objeto de contexto de Lambda para recuperar información de funciones de C\$1
<a name="csharp-context"></a>

Cuando Lambda ejecuta su función, pasa un objeto context al [controlador](csharp-handler.md). Este objeto proporciona propiedades con información acerca de la invocación, la función y el entorno de ejecución.

**Propiedades de context**
+ `FunctionName`: el nombre de la función de Lambda.
+ `FunctionVersion`: la [versión](configuration-versions.md) de la función.
+ `InvokedFunctionArn`: el nombre de recurso de Amazon (ARN) que se utiliza para invocar esta función. Indica si el invocador especificó un número de versión o alias.
+ `MemoryLimitInMB`: cantidad de memoria asignada a la función.
+ `AwsRequestId`: el identificador de la solicitud de invocación.
+ `LogGroupName`: grupo de registros de para la función.
+ `LogStreamName`: el flujo de registro de la instancia de la función.
+ `RemainingTime`(`TimeSpan`): el número de milisegundos que quedan antes del tiempo de espera de la ejecución.
+ `Identity`: (aplicaciones móviles) Información acerca de la identidad de Amazon Cognito que autorizó la solicitud.
+ `ClientContext`: (aplicaciones móviles) Contexto de cliente proporcionado a Lambda por la aplicación cliente.
+ `Logger`: el [objeto logger](csharp-logging.md) para la función.

Puede utilizar información en el objeto `ILambdaContext` para generar información sobre la invocación de su función con fines de supervisión. El código siguiente proporciona un ejemplo de cómo agregar información de contexto a un marco de registro estructurado. En este ejemplo, la función agrega `AwsRequestId` a los resultados del registro. La función también utiliza la propiedad `RemainingTime` para cancelar una tarea en vuelo si está a punto de agotarse el tiempo de espera de la función de Lambda.

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

# Registro y supervisión de las funciones de Lambda de C\$1
<a name="csharp-logging"></a>

AWS Lambda supervisa de forma automática funciones de Lambda y envía entradas de registros a Amazon CloudWatch. Su función de Lambda viene con un grupo de registros de Registros de CloudWatch y con un flujo de registro para cada instancia de su función. El entorno de tiempo de ejecución de Lambda envía detalles sobre cada invocación y otros resultados del código de su función al flujo de registro. Para obtener más información acerca de Registros de CloudWatch, consulte [Envío de registros de funciones de Lambda a Registros de CloudWatch](monitoring-cloudwatchlogs.md).

**Topics**
+ [

## Crear una función que devuelve registros
](#csharp-logging-output)
+ [

## Uso de los controles de registro avanzados de Lambda con .NET
](#csharp-logging-advanced)
+ [

## Herramientas y bibliotecas de registro adicionales
](#csharp-tools-libraries)
+ [

## Uso de Powertools para AWS Lambda (.NET) y AWS SAM para el registro estructurado
](#dotnet-logging-sam)
+ [

## Visualización de los registros en la consola de Lambda
](#csharp-logging-console)
+ [

## Visualización de los registros de en la consola de CloudWatch
](#csharp-logging-cwconsole)
+ [

## Visualización de los registros mediante la AWS Command Line Interface (AWS CLI)
](#csharp-logging-cli)
+ [

## Eliminación de registros
](#csharp-logging-delete)

## Crear una función que devuelve registros
<a name="csharp-logging-output"></a>

Para generar registros desde el código de su función, puede utilizar el [ILambdaLogger](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.Core/ILambdaLogger.cs) en el objeto de contexto, los métodos de la [Clase de consola](https://docs.microsoft.com/en-us/dotnet/api/system.console), o cualquier biblioteca de registro que escriba en `stdout` o `stderr`.

El tiempo de ejecución de .NET registra las líneas `START`, `END` y `REPORT` de cada invocación. La línea del informe proporciona los siguientes detalles.

**Campos de datos de línea REPORT**
+ **RequestId**: el ID de solicitud único para la invocación.
+ **Duración**: la cantidad de tiempo que el método de controlador de función pasó procesando el evento.
+ **Duración facturada**: la cantidad de tiempo facturado por la invocación.
+ **Tamaño de memoria**: la cantidad de memoria asignada a la función.
+ **Máximo de memoria usada**: la cantidad de memoria utilizada por la función. Cuando las invocaciones comparten un entorno de ejecución, Lambda informa de la memoria máxima utilizada en todas las invocaciones. Este comportamiento puede dar como resultado un valor notificado superior al esperado.
+ **Duración de inicio**: para la primera solicitud servida, la cantidad de tiempo que tardó el tiempo de ejecución en cargar la función y ejecutar código fuera del método del controlador.
+ **TraceId de XRAY**: para las solicitudes rastreadas, el [ID de seguimientode AWS X-Ray](services-xray.md).
+ **SegmentId**: para solicitudes rastreadas, el ID del segmento de X-Ray.
+ **Muestras**: para solicitudes rastreadas, el resultado del muestreo.

## Uso de los controles de registro avanzados de Lambda con .NET
<a name="csharp-logging-advanced"></a>

Para tener más control sobre cómo se registran, procesan y consumen los registros de las funciones, puede configurar las siguientes opciones de registro para los tiempos de ejecución de .NET admitidos:
+ **Formato de registro**: seleccione entre texto sin formato y el formato JSON estructurado para los registros de su función
+ **Nivel de registro**: para los registros en formato JSON, elija el nivel de detalle de los registros que Lambda envía a CloudWatch, como ERROR, DEBUG o INFO
+ **Grupo de registro**: elija el grupo de registro de CloudWatch al que su función envía los registros

Para obtener más información sobre estas opciones de registro e instrucciones sobre cómo configurar la función para utilizarlas, consulte [Configuración de controles de registro avanzados para las funciones de Lambda](monitoring-logs.md#monitoring-cloudwatchlogs-advanced).

Para usar las opciones de formato y nivel de registro con las funciones de Lambda de .NET, consulte las instrucciones de las siguientes secciones.

### Uso del formato de registro JSON estructurado con .NET
<a name="csharp-logging-advanced-JSON"></a>

Si selecciona JSON para el formato de registro de la función, Lambda enviará los registros de salida mediante [ILambdaLogger](https://github.com/aws/aws-lambda-dotnet/blob/master/Libraries/src/Amazon.Lambda.Core/ILambdaLogger.cs) como JSON estructurado. Cada objeto de registro JSON contiene, por lo menos, cinco pares clave-valor con las siguientes claves:
+ `"timestamp"`: la hora en que se generó el mensaje de registro
+ `"level"`: el nivel de registro asignado al mensaje
+ `"requestId"`: el ID de solicitud único para la invocación de la función
+ `"traceId"`: la variable de entorno `_X_AMZN_TRACE_ID`
+ `"message"`: el contenido del mensaje de registro

La instancia `ILambdaLogger` puede agregar pares clave-valor adicionales, por ejemplo, al registrar excepciones. También puede proporcionar sus propios parámetros adicionales, tal y como se describe en la sección [Parámetros de registro proporcionados por el cliente](#csharp-logging-advanced-JSON-user-supplied).

**nota**  
Si su código ya usa otra biblioteca de registro para generar registros con formato JSON, asegúrese de que el formato de registro de la función esté establecido en texto sin formato. Si se establece el formato de registro en JSON, los resultados del registro se codificarán doblemente.

En el siguiente ejemplo de comando de registro, se muestra cómo escribir un mensaje de registro con el nivel `INFO`.

**Example Código de registro en .NET**  

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

También puede utilizar un método de registro genérico que tome el nivel de registro como argumento, como se muestra en el siguiente ejemplo.

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

La salida del registro generada por estos fragmentos de código de ejemplo se capturaría en Registros de CloudWatch de la siguiente manera:

**Example Entrada de registro JSON**  

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

**nota**  
Si configura el formato de registro de la función para que utilice texto sin formato en lugar de JSON, el nivel de registro capturado en el mensaje sigue la convención de Microsoft de usar una etiqueta de cuatro caracteres. Por ejemplo, un nivel de registro de `Debug` se representa en el mensaje como `dbug`.  
Al configurar la función para utilizar registros con formato JSON, el nivel de registro capturado en el registro utiliza la etiqueta completa, como se muestra en el registro de registro JSON de ejemplo.

Si no asigna un nivel a la salida del registro, Lambda asignará el nivel INFO automáticamente.

#### Registro de excepciones en JSON
<a name="csharp-logging-advanced-JSON-exceptions"></a>

Si utiliza el registro JSON estructurado con `ILambdaLogger`, puede registrar las excepciones en su código, como se muestra en el siguiente ejemplo.

**Example uso del registro de excepciones**  

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

El resultado en formato de registro de este código se muestra en el ejemplo siguiente de JSON. Tenga en cuenta que la propiedad `message` de JSON se rellena con el argumento message proporcionado en la llamada `LogWarning`, mientras que la propiedad `errorMessage` proviene de la propiedad `Message` de la propia excepción.

**Example Entrada de registro JSON**  

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

Si el formato de registro de la función está establecido en JSON, Lambda también genera mensajes de registro con formato JSON cuando el código arroja una excepción no detectada. En el siguiente ejemplo, el fragmento de código y el mensaje de registro muestran cómo se registran las excepciones no detectadas.

**Example código de excepción**  

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

**Example Entrada de registro JSON**  

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

#### Parámetros de registro proporcionados por el cliente
<a name="csharp-logging-advanced-JSON-user-supplied"></a>

Con los mensajes de registro con formato JSON, puede proporcionar parámetros de registro adicionales e incluirlos en el registro `message`. En el siguiente ejemplo de fragmento de código, se muestra un comando para agregar dos parámetros proporcionados por el usuario denominados `retryAttempt` y `uri`. En el ejemplo, el valor de estos parámetros proviene de los argumentos `retryAttempt` y `uriDestination` transferidos al comando logging.

**Example Comando de registro JSON con parámetros adicionales**  

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

El resultado del mensaje de registro de este comando se muestra en el ejemplo siguiente de JSON.

**Example Entrada de registro JSON**  

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

**sugerencia**  
También puede usar propiedades posicionales en lugar de nombres al especificar parámetros adicionales. Por ejemplo, el comando de registro en el ejemplo anterior también podría escribirse de la siguiente manera:  

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

Tenga en cuenta que cuando suministra parámetros adicionales de registro, Lambda los captura como propiedades de nivel superior en el registro de registros en JSON. Este enfoque difiere de algunas bibliotecas populares de registro en .NET, como `Serilog`, que captura parámetros adicionales en un objeto secundario separado.

Si el argumento que proporciona para un parámetro adicional es un objeto complejo, Lambda utilizará el método `ToString()` de forma predeterminada para proporcionar el valor. Para indicar que un argumento debe estar serializado en JSON, utilice el prefijo `@` como se muestra en el siguiente fragmento de código. En este ejemplo, `User` es un objeto con propiedades `FirstName` y `LastName`.

**Example Comando de registro JSON con objeto serializado JSON**  

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

El resultado del mensaje de registro de este comando se muestra en el ejemplo siguiente de JSON.

**Example Entrada de registro JSON**  

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

Si el argumento de un parámetro adicional es una matriz o implementa `IList` o `IDictionary`, Lambda agrega el argumento al mensaje de registro JSON como una matriz, como se muestra en el siguiente ejemplo de registro JSON. En este ejemplo, `{users}` toma un argumento `IList` que contiene instancias de la propiedad `User` con el mismo formato que en el ejemplo anterior. Lambda convierte a `IList` en una matriz y cada valor se crea mediante el método `ToString`.

**Example Registro de registro JSON con un argumento `IList`**  

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

También puede serializar la lista en JSON mediante el prefijo `@` del comando de registro. En el siguiente ejemplo de registro JSON, la propiedad `users` está serializada en JSON.

**Example Registro de registros JSON con un argumento `IList` serializado JSON**  

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

### Uso del filtrado de registros con .NET
<a name="csharp-logging-advanced-levels"></a>

Al configurar el filtrado de registros, puede elegir enviar solo los registros de un nivel de detalle específico o inferior a los Registros de CloudWatch. Para obtener información sobre cómo configurar el filtrado a nivel de registro para su función, consulte [Filtrado a nivel de registro](monitoring-cloudwatchlogs-log-level.md).

Para que AWS Lambda filtre los mensajes de registro por nivel de registro, puede usar registros con formato JSON o usar los métodos. NET `Console` para generar mensajes de registro. Para crear registros con formato JSON, [configure el tipo de registro de su función en JSON](monitoring-cloudwatchlogs-logformat.md#monitoring-cloudwatchlogs-set-format) y use la instancia `ILambdaLogger`.

Con los registros en formato JSON, Lambda filtra sus salidas de registro mediante el par clave-valor “level” en el objeto JSON descrito en [Uso del formato de registro JSON estructurado con .NET](#csharp-logging-advanced-JSON).

Si utiliza los métodos .NET `Console` para escribir mensajes en los Registros de CloudWatch, Lambda aplicará los siguientes niveles de registro a los mensajes:
+ **Método Console.WriteLine**: Lambda aplica un nivel de registro de `INFO`
+ **Método Console.Error**: Lambda aplica un nivel de registro de `ERROR`

Cuando configura la función para que utilice el filtrado a nivel de registro, debe seleccionar una de las siguientes opciones para el nivel de registros que desea que Lambda envíe a los Registros de CloudWatch. Observe la asignación de los niveles de registro utilizados por Lambda con los niveles estándar de Microsoft utilizados por .NET `ILambdaLogger`.


| Nivel de registro de Lambda | Nivel de Microsoft equivalente | Uso estándar | 
| --- | --- | --- | 
| TRACE (más detallado) | Rastreo | La información más detallada que se utiliza para rastrear la ruta de ejecución del código | 
| DEBUG | Debug | Información detallada para la depuración del sistema | 
| INFO | Información | Mensajes que registran el funcionamiento normal de su función | 
| WARN | Advertencia | Mensajes sobre posibles errores que pueden provocar un comportamiento inesperado si no se abordan | 
| ERROR | Error | Mensajes sobre problemas que impiden que el código funcione según lo esperado | 
| FATAL (menos detallado) | Critico | Mensajes sobre errores graves que hacen que la aplicación deje de funcionar | 

Lambda envía los registros del nivel de detalle seleccionado e inferior a CloudWatch. Por ejemplo, si configura un nivel de registro de WARN, Lambda enviará los registros correspondientes a los niveles WARN, ERROR y FATAL.

## Herramientas y bibliotecas de registro adicionales
<a name="csharp-tools-libraries"></a>

[Powertools para AWS Lambda (.NET)](https://docs.aws.amazon.com/powertools/dotnet/) es un kit de herramientas para desarrolladores destinado a implementar prácticas recomendadas sin servidor y aumentar la velocidad de los desarrolladores. La [utilidad de registro](https://docs.aws.amazon.com/powertools/dotnet/core/logging/) proporciona un logger optimizado para Lambda que incluye información adicional sobre el contexto de la función en todas las funciones con un resultado estructurado como JSON. Utilice esta utilidad para hacer lo siguiente:
+ Capturar campos clave del contexto de Lambda, arranque en frío y resultados de registro de estructuras como JSON
+ Registrar los eventos de invocación de Lambda cuando se le indique (desactivado de forma predeterminada)
+ Imprimir todos los registros solo para un porcentaje de las invocaciones mediante el muestreo de registros (desactivado de forma predeterminada)
+ Agregar claves adicionales al registro estructurado en cualquier momento
+ Utilizar un formateador de registros personalizado (traiga su propio formateador) para generar registros en una estructura compatible con el RFC de registro de su organización

## Uso de Powertools para AWS Lambda (.NET) y AWS SAM para el registro estructurado
<a name="dotnet-logging-sam"></a>

Siga los pasos que figuran a continuación para descargar, crear e implementar una aplicación de muestra “Hola, mundo” de C\$1 con módulos de [Powertools para AWS Lambda (.NET)](https://docs.powertools.aws.dev/lambda-dotnet) integrados mediante AWS SAM. Esta aplicación implementa un backend de API básico y utiliza Powertools para emitir registros, métricas y seguimiento. Consta de un punto de conexión de Amazon API Gateway y una función de Lambda. Cuando se envía una solicitud GET al punto de conexión de API Gateway, la función de Lambda se invoca, envía registros y métricas a CloudWatch mediante Embedded Metric Format y envía seguimiento a AWS X-Ray. La función devuelve el mensaje `hello world`.

**Requisitos previos**

Para completar los pasos de esta sección, debe disponer de lo siguiente:
+ .NET 8
+ [AWS CLI versión 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS SAM Versión 1.75 o posterior de la CLI de](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html). Si tiene una versión anterior de la CLI de AWS SAM, consulte [Actualización de la CLI de AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade).

**Implementar una aplicación de ejemplo de AWS SAM**

1. Inicialice la aplicación utilizando la plantilla de TypeScript de tipo Hola Mundo.

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

1. Compile la aplicación.

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

1. Implemente la aplicación.

   ```
   sam deploy --guided
   ```

1. Siga las indicaciones que aparecen en pantalla. Para aceptar las opciones predeterminadas proporcionadas en la experiencia interactiva, oprima `Enter`.
**nota**  
En **HelloWorldFunction es posible que no tenga definida la autorización, ¿está bien?**, asegúrese de ingresar `y`.

1. Obtenga la URL de la aplicación implementada:

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

1. Invoque el punto de conexión de la API:

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

   Si se realiza de forma correcta, verá el siguiente resultado:

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

1. Para obtener los registros de la función, ejecute [sam logs](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-logs.html). Para obtener más información, consulte [Uso de registros](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-logging.html) en la *Guía para desarrolladores de AWS Serverless Application Model*.

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

   El resultado del registro tendrá este aspecto:

   ```
   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. Se trata de un punto de conexión de API pública al que se puede acceder a través de Internet. Se recomienda eliminar el punto de conexión después de las pruebas.

   ```
   sam delete
   ```

### Administración de retención de registros
<a name="csharp-log-retention"></a>

Los grupos de registro no se eliminan automáticamente cuando se elimina una función. Para evitar almacenar registros de forma indefinida, elimine el grupo de registros o configure un periodo de retención después del cual CloudWatch los eliminará de forma automática. Para configurar la retención de registros, agregue lo siguiente a la plantilla de AWS SAM:

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

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

## Visualización de los registros en la consola de Lambda
<a name="csharp-logging-console"></a>

Puede utilizar la consola de Lambda para ver la salida del registro después de invocar una función de Lambda.

Si su código se puede probar desde el editor de **código** integrado, encontrará los registros en los **resultados de ejecución**. Cuando utilice la característica de prueba de la consola para invocar una función, encontrará la **Salida de registro** en la sección de **Detalles**.

## Visualización de los registros de en la consola de CloudWatch
<a name="csharp-logging-cwconsole"></a>

Puede utilizar la consola Amazon CloudWatch para ver los registros de todas las invocaciones de funciones de Lambda.

**Visualización de los registros en la consola CloudWatch**

1. En la consola de CloudWatch, abra la [página de grupos de registro](https://console.aws.amazon.com/cloudwatch/home?#logs:).

1. Seleccione el grupo de registros para su función (**/aws/lambda/*your-function-name***).

1. Elija una secuencia de registro.

Cada flujo de registro se corresponde con una [instancia de su función](lambda-runtime-environment.md). Aparece un flujo de registro cuando actualiza la función de Lambda y cuando se crean instancias adicionales para gestionar invocaciones simultáneas. Para encontrar registros para una invocación específica, le recomendamos que interfiera su función con AWS X-Ray. X-Ray registra los detalles sobre la solicitud y el flujo de registro en el seguimiento.

## Visualización de los registros mediante la AWS Command Line Interface (AWS CLI)
<a name="csharp-logging-cli"></a>

La AWS CLI es una herramienta de código abierto que lo habilita para interactuar con los servicios de AWS mediante el uso de comandos en el intérprete de comandos de la línea de comandos. Para completar los pasos de esta sección, debe disponer de la [versión 2 de la AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).

Puede utilizar la [CLI de AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) para recuperar registros de una invocación mediante la opción de comando `--log-type`. La respuesta contiene un campo `LogResult` que contiene hasta 4 KB de registros con codificación base64 a partir de la invocación.

**Example recuperar un ID de registro**  
En el ejemplo siguiente se muestra cómo recuperar un *ID de registro* del campo `LogResult` para una función denominada `my-function`.  

```
aws lambda invoke --function-name my-function out --log-type Tail
```
Debería ver los siguientes datos de salida:  

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

**Example decodificar los registros**  
En el mismo símbolo del sistema, utilice la utilidad `base64` para decodificar los registros. En el ejemplo siguiente se muestra cómo recuperar registros codificados en base64 para `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
```
La opción **cli-binary-format** es obligatoria si va a utilizar la versión 2 de la AWS CLI. Para que esta sea la configuración predeterminada, ejecute `aws configure set cli-binary-format raw-in-base64-out`. Para obtener más información, consulte [Opciones de la línea de comandos globales compatibles con AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) en la *Guía del usuario de la AWS Command Line Interface versión 2*.  
Debería ver los siguientes datos de salida:  

```
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
```
La utilidad `base64` está disponible en Linux, macOS y [Ubuntu en Windows](https://docs.microsoft.com/en-us/windows/wsl/install-win10). Es posible que los usuarios de macOS necesiten usar `base64 -D`.

**Example get-logs.sh script**  
En el mismo símbolo del sistema, utilice el siguiente script para descargar los últimos cinco eventos de registro. El script utiliza `sed` para eliminar las comillas del archivo de salida y permanece inactivo durante 15 segundos para dar tiempo a que los registros estén disponibles. La salida incluye la respuesta de Lambda y la salida del comando `get-log-events`.   
Copie el contenido de la siguiente muestra de código y guárdelo en su directorio de proyecto Lambda como `get-logs.sh`.  
La opción **cli-binary-format** es obligatoria si va a utilizar la versión 2 de la AWS CLI. Para que esta sea la configuración predeterminada, ejecute `aws configure set cli-binary-format raw-in-base64-out`. Para obtener más información, consulte [Opciones de la línea de comandos globales compatibles con AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-options.html#cli-configure-options-list) en la *Guía del usuario de la AWS Command Line Interface versión 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 y Linux (solamente)**  
En el mismo símbolo del sistema, es posible que los usuarios de macOS y Linux necesiten ejecutar el siguiente comando para asegurarse de que el script es ejecutable.  

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

**Example recuperar los últimos cinco eventos de registro**  
En el mismo símbolo del sistema, ejecute el siguiente script para obtener los últimos cinco eventos de registro.  

```
./get-logs.sh
```
Debería ver los siguientes datos de salida:  

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

## Eliminación de registros
<a name="csharp-logging-delete"></a>

Los grupos de registro no se eliminan automáticamente cuando se elimina una función. Para evitar almacenar registros indefinidamente, elimine el grupo de registros o [configure un periodo de retención](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/Working-with-log-groups-and-streams.html#SettingLogRetention) después de lo cual los registros se eliminan automáticamente.

# Instrumentación de código C\$1 en AWS Lambda
<a name="csharp-tracing"></a>

Lambda se integra con AWS X-Ray para permitirle seguir, depurar y optimizar aplicaciones de Lambda. Puede utilizar X-Ray para seguir una solicitud mientras atraviesa los recursos de la aplicación, que pueden incluir funciones de Lambda y otros servicios de AWS.

Para enviar datos de seguimiento a X-Ray, puede utilizar una de estas tres bibliotecas de SDK:
+ [AWS Distro for OpenTelemetry (ADOT)](https://aws.amazon.com/otel): una distribución segura, lista para producción y con soporte de AWS del OpenTelemetry (OTel) SDK.
+ [AWS X-Ray SDK para .NET](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-dotnet.html) – un SDK para generar y enviar datos de seguimiento a X-Ray.
+ [Powertools para AWS Lambda (.NET)](https://docs.aws.amazon.com/powertools/dotnet/): un kit de herramientas para desarrolladores destinado a implementar prácticas recomendadas sin servidor y aumentar la velocidad de los desarrolladores.

Cada uno de los SDK ofrecen formas de enviar los datos de telemetría al servicio X-Ray. Tras ello, se puede utilizar X-Ray para consultar, filtrar y obtener información sobre las métricas de rendimiento de la aplicación con el fin de identificar problemas y oportunidades de optimización.

**importante**  
Los SDK de X-Ray y Powertools para AWS Lambda son parte de una solución de instrumentación completamente integrada que ofrece AWS. Las capas Lambda de ADOT forman parte de un estándar que abarca todo el sector para la instrumentación de seguimiento que recopila más datos en general, pero es posible que no sean adecuadas para todos los casos de uso. Puede implementar el seguimiento integral en X-Ray con cualquiera de las soluciones. Para obtener más información sobre cuál elegir, consulte [Elegir entre SDK de AWS Distro para OpenTelemetry y X-Ray](https://docs.aws.amazon.com/xray/latest/devguide/xray-instrumenting-your-app.html#xray-instrumenting-choosing).

**Topics**
+ [

## Uso de Powertools para AWS Lambda (.NET) y AWS SAM para el seguimiento
](#dotnet-tracing-sam)
+ [

## Uso del SDK de X-Ray para instrumentar las funciones de .NET
](#dotnet-xray-sdk)
+ [

## Activación del seguimiento con la consola de Lambda
](#dotnet-tracing-console)
+ [

## Activación del seguimiento con la API de Lambda
](#dotnet-tracing-api)
+ [

## Activación del seguimiento con CloudFormation
](#dotnet-tracing-cloudformation)
+ [

## Interpretación de un seguimiento de X-Ray
](#dotnet-tracing-interpretation)

## Uso de Powertools para AWS Lambda (.NET) y AWS SAM para el seguimiento
<a name="dotnet-tracing-sam"></a>

Siga los pasos que figuran a continuación para descargar, crear e implementar una aplicación de muestra “Hola, mundo” de C\$1 con módulos de [Powertools para AWS Lambda (.NET)](https://docs.powertools.aws.dev/lambda-dotnet) integrados mediante AWS SAM. Esta aplicación implementa un backend de API básico y utiliza Powertools para emitir registros, métricas y seguimiento. Consta de un punto de conexión de Amazon API Gateway y una función de Lambda. Cuando se envía una solicitud GET al punto de conexión de API Gateway, la función de Lambda se invoca, envía registros y métricas a CloudWatch mediante Embedded Metric Format y envía seguimiento a AWS X-Ray. La función devuelve el mensaje hello world.

**Requisitos previos**

Para completar los pasos de esta sección, debe disponer de lo siguiente:
+ .NET 8
+ [AWS CLI versión 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [AWS SAM Versión 1.75 o posterior de la CLI de](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html). Si tiene una versión anterior de la CLI de AWS SAM, consulte [Actualización de la CLI de AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/manage-sam-cli-versions.html#manage-sam-cli-versions-upgrade).

**Implementar una aplicación de ejemplo de AWS SAM**

1. Inicialice la aplicación utilizando la plantilla de TypeScript de tipo Hola Mundo.

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

1. Compile la aplicación.

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

1. Implemente la aplicación.

   ```
   sam deploy --guided
   ```

1. Siga las indicaciones que aparecen en pantalla. Para aceptar las opciones predeterminadas proporcionadas en la experiencia interactiva, oprima `Enter`.
**nota**  
En **HelloWorldFunction es posible que no tenga definida la autorización, ¿está bien?**, asegúrese de ingresar `y`.

1. Obtenga la URL de la aplicación implementada:

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

1. Invoque el punto de conexión de la API:

   ```
   curl <URL_FROM_PREVIOUS_STEP>
   ```

   Si se realiza de forma correcta, verá el siguiente resultado:

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

1. Para obtener el seguimiento de la función, ejecute [sam traces](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-cli-command-reference-sam-traces.html).

   ```
   sam traces
   ```

   El resultado del seguimiento tendrá este aspecto:

   ```
   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. Se trata de un punto de conexión de API pública al que se puede acceder a través de Internet. Se recomienda eliminar el punto de conexión después de las pruebas.

   ```
   sam delete
   ```

X-Ray no sigue todas las solicitudes realizadas a la aplicación. X-Ray aplica un algoritmo de muestreo para garantizar que el seguimiento sea eficiente, a la vez que proporciona una muestra representativa de todas las solicitudes. La tasa de muestreo es 1 solicitud por segundo y un 5 por ciento de las solicitudes adicionales. La frecuencia de muestreo de X-Ray no se puede configurar para las funciones.

## Uso del SDK de X-Ray para instrumentar las funciones de .NET
<a name="dotnet-xray-sdk"></a>

Puede instrumentar su código de función para registrar metadatos y rastrear llamadas descendentes. Para registrar detalles sobre las llamadas que realiza su función a otros recursos y servicios, use el AWS X-Ray SDK para .NET. Para obtener el SDK, agregue los paquetes `AWSXRayRecorder` al archivo de proyecto.

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

Hay una gama de paquetes Nuget que proporcionan instrumentación automática para SDKs AWS, Entity Framework y solicitudes HTTP. Para ver el conjunto completo de opciones de configuración, consulte [SDK AWS X-Ray para .NET](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-dotnet.html) en la *Guía para desarrolladores AWS X-Ray*.

Una vez que haya agregado los paquetes Nuget deseados, configure la instrumentación automática. La mejor práctica es realizar esta configuración fuera de la función de control de la función. Esto le permite aprovechar la reutilización del entorno de ejecución para mejorar el rendimiento de la función. En el siguiente ejemplo de código, se llama al método `RegisterXRayForAllServices` en el constructor de la función para añadir instrumentación a todas las llamadas al SDK de AWS.

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

namespace GetProductHandler;

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

## Activación del seguimiento con la consola de Lambda
<a name="dotnet-tracing-console"></a>

Para activar el seguimiento activo de la función Lambda mediante la consola, siga estos pasos:

**Cómo activar el seguimiento activo**

1. Abra la [página de Funciones](https://console.aws.amazon.com/lambda/home#/functions) en la consola de Lambda.

1. Elija una función.

1. Elija **Configuration** (Configuración), y luego **Monitoring and operations tools** (Herramientas de supervisión y operaciones).

1. En **Herramientas de monitorización adicionales**, elija **Editar**.

1. En **CloudWatch Application Signals y AWS X-Ray**, seleccione **Habilitar** para **Seguimientos de servicios de Lambda**.

1. Seleccione **Save**.

## Activación del seguimiento con la API de Lambda
<a name="dotnet-tracing-api"></a>

Configure el rastreo en la función Lambda con AWS CLI o SDK de AWS, utilice las siguientes operaciones de API:
+ [UpdateFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionConfiguration.html)
+ [GetFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionConfiguration.html)
+ [CreateFunction](https://docs.aws.amazon.com/lambda/latest/api/API_CreateFunction.html)

El siguiente comando de ejemplo de la AWS CLI habilita el seguimiento activo en una función llamada **my-function**.

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

El modo de seguimiento forma parte de la configuración específica de la versión, cuando se publica una versión de la función. No se puede cambiar el modo de seguimiento de una versión publicada.

## Activación del seguimiento con CloudFormation
<a name="dotnet-tracing-cloudformation"></a>

Para activar el seguimiento en un recurso de `AWS::Lambda::Function` de una plantilla de CloudFormation, utilice la propiedad `TracingConfig`.

**Example [función-inline.yml](https://github.com/awsdocs/aws-lambda-developer-guide/blob/master/templates/function-inline.yml): configuración de rastreo**  

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

Para un recurso AWS Serverless Application Model de AWS SAM (`AWS::Serverless::Function`) , utilice la propiedad `Tracing`.

**Example [template.yml](https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-nodejs/template.yml): configuración de rastreo**  

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

## Interpretación de un seguimiento de X-Ray
<a name="dotnet-tracing-interpretation"></a>

La función necesita permiso para cargar datos de rastreo en X-Ray. Cuando activa el rastreo activo en la consola de Lambda, Lambda agrega los permisos necesarios al [rol de ejecución](lambda-intro-execution-role.md) de la función. De lo contrario, agregue la política [AWSXRayDaemonWriteAccess](https://console.aws.amazon.com/iam/home#/policies/arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess) al rol de ejecución.

Después de configurar el seguimiento activo, se pueden observar solicitudes específicas a través de la aplicación. El [gráfico de servicios de X-Ray](https://docs.aws.amazon.com/xray/latest/devguide/aws-xray.html#xray-concepts-servicegraph) muestra información sobre la aplicación y todos sus componentes. En el siguiente ejemplo, se muestra una aplicación con dos funciones. La función principal procesa eventos y, a veces, devuelve errores. La segunda función de la cadena procesa los errores que aparecen en el primer grupo de registros y utiliza el SDK de AWS para llamar a X-Ray, Amazon Simple Storage Service (Amazon S3) y Registros de Amazon CloudWatch.

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


X-Ray no sigue todas las solicitudes realizadas a la aplicación. X-Ray aplica un algoritmo de muestreo para garantizar que el seguimiento sea eficiente, a la vez que proporciona una muestra representativa de todas las solicitudes. La tasa de muestreo es 1 solicitud por segundo y un 5 por ciento de las solicitudes adicionales. La frecuencia de muestreo de X-Ray no se puede configurar para las funciones.

En X-Ray, un *seguimiento* registra información sobre una solicitud procesada por uno o varios *servicios*. Lambda registra 2 segmentos por seguimiento, lo que crea dos nodos en el gráfico de servicios. La siguiente imagen resalta estos dos nodos:

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


El primer nodo, situado a la izquierda, representa el servicio de Lambda, que recibe la solicitud de invocación. El segundo nodo representa la función Lambda específica. En el siguiente ejemplo, se muestra un seguimiento con estos dos segmentos. Ambos se denominan **my-function**, pero uno tiene un origen de `AWS::Lambda` y el otro tiene origen de `AWS::Lambda::Function`. Si el segmento `AWS::Lambda` muestra un error, el servicio Lambda tuvo un problema. Si el segmento `AWS::Lambda::Function` muestra un error, la función tuvo un problema.

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


En este ejemplo, el segmento `AWS::Lambda::Function` aparece ampliado para mostrar los tres subsegmentos.

**nota**  
AWS está implementando cambios en el servicio Lambda. Debido a estos cambios, es posible que vea pequeñas diferencias entre la estructura y el contenido de los mensajes de registro del sistema y los segmentos de rastro emitidos por diferentes funciones de Lambda en su Cuenta de AWS.  
El rastro de ejemplo que se muestra aquí ilustra el segmento de función de estilo antiguo. Las diferencias entre los segmentos de estilo antiguo y nuevo se describen en los párrafos siguientes.  
Estos cambios se implementarán en las próximas semanas y todas las funciones de todas las Regiones de AWS, excepto en las regiones de China y GovCloud, pasarán a utilizar el nuevo formato de mensajes de registro y segmentos de rastro.

El segmento de función de estilo antiguo contiene los siguientes subsegmentos:
+ **Inicialización**: representa el tiempo dedicado a cargar la función y ejecutar el [código de inicialización](foundation-progmodel.md). Este subsegmento aparece únicamente para el primer evento que procesa cada instancia de la función.
+ **Invocación**: representa el tiempo dedicado a ejecutar el código del controlador.
+ **Sobrecarga**: representa el tiempo que el tiempo de ejecución de Lambda dedica a prepararse para gestionar el siguiente evento.

El segmento de función de estilo nuevo no contiene ningún subsegmento de `Invocation`. En cambio, los subsegmentos de clientes se adjuntan directamente al segmento de la función. Para obtener más información sobre la estructura de los segmentos de funciones de estilo antiguo y nuevo, consulte [Comprensión de los rastros](services-xray.md#services-xray-traces).

También puede instrumentar clientes HTTP, registrar consultas SQL y crear subsegmentos personalizados con anotaciones y metadatos. Para obtener más información, consulte [AWS X-Ray SDK para .NET](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-dotnet.html) en la *Guía para desarrolladores de AWS X-Ray*.

**Precios**  
Puede utilizar el seguimiento de X-Ray de manera gratuita cada mes hasta un límite determinado como parte del nivel Gratuito de AWS. A partir de ese umbral, X-Ray realiza cargos por almacenamiento y recuperación del seguimiento. Para obtener más información, consulte [Precios de AWS X-Ray](https://aws.amazon.com/xray/pricing/).

# Prueba de funciones de AWS Lambda en C\$1
<a name="dotnet-csharp-testing"></a>

**nota**  
Consulte el capítulo [Prueba de funciones](testing-guide.md) para obtener una introducción completa a las técnicas y prácticas recomendadas para probar soluciones sin servidor. 

 Para probar las funciones sin servidor, se utilizan tipos y técnicas de prueba tradicionales, pero también se debe considerar la posibilidad de probar las aplicaciones sin servidor en conjunto. Las pruebas basadas en la nube proporcionan la medida **más precisa** de la calidad tanto de las funciones como de las aplicaciones sin servidor. 

 Una arquitectura de aplicaciones sin servidor incluye servicios administrados que proporcionan las funcionalidades críticas de las aplicaciones mediante llamadas a la API. Por este motivo, el ciclo de desarrollo debe incluir pruebas automatizadas que verifiquen las funcionalidades cuando la función y los servicios interactúen. 

 Si no crea pruebas basadas en la nube, pueden surgir problemas debido a las diferencias entre su entorno local y el entorno implementado. El proceso de integración continua debe ejecutar pruebas con un conjunto de recursos aprovisionados en la nube antes de promover el código al siguiente entorno de implementación, como el control de calidad, el ensayo o la producción. 

 Siga leyendo esta breve guía para obtener información sobre las estrategias de prueba para aplicaciones sin servidor, o visite el [repositorio de ejemplos de pruebas sin servidor](https://github.com/aws-samples/serverless-test-samples) a fin de profundizar en ejemplos prácticos y específicos para el lenguaje y el tiempo de ejecución de su elección. 

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

 Para las pruebas sin servidor, seguirá escribiendo pruebas *unitarias*, *de integración* e *integrales*. 
+ **Pruebas unitarias**: pruebas que se ejecutan en un bloque de código aislado. Por ejemplo, verificar la lógica empresarial para calcular los gastos de envío en función de un elemento y un destino determinados.
+ **Pruebas de integración**: pruebas en las que participan dos o más componentes o servicios que interactúan, normalmente en un entorno de nube. Por ejemplo, verificar si una función procesa los eventos de una cola.
+ **Pruebas integrales**: pruebas que verifican el comportamiento de toda una aplicación. Por ejemplo, garantizar que la infraestructura esté configurada correctamente y que los eventos fluyan entre los servicios tal como se espera para registrar el pedido de un cliente.

## Pruebas de aplicaciones sin servidor
<a name="dotnet-csharp-testing-techniques-for-serverless-applications"></a>

 Por lo general, utilizará una combinación de métodos para probar el código de sus aplicaciones sin servidor, como las pruebas en la nube, las pruebas con simulaciones y, en ocasiones, las pruebas con emuladores. 

### Pruebas en la nube
<a name="dotnet-csharp-testing-in-the-cloud"></a>

 Las pruebas en la nube son valiosas para todas las fases de las pruebas, incluidas las pruebas unitarias, las pruebas de integración y las pruebas integrales. Las pruebas se ejecutan con el código implementado en la nube y se interactúa con los servicios basados en la nube. Este enfoque proporciona la medida **más precisa** de la calidad del código. 

 Una forma práctica de depurar la función de Lambda en la nube es a través de la consola con un evento de prueba. Un *evento de prueba* es una entrada JSON a su función. Si la función no requiere una entrada, el evento puede ser un documento JSON vacío `({})`. La consola proporciona ejemplos de eventos para una variedad de integraciones de servicios. Tras crear un evento en la consola, puede compartirlo con su equipo para que las pruebas sean más sencillas y coherentes. 

**nota**  
[Probar una función en la consola](testing-functions.md) es una forma rápida de empezar, pero la automatización de los ciclos de prueba garantiza la calidad de la aplicación y la velocidad de desarrollo. 

### Herramientas para pruebas
<a name="dotnet-csharp-testing-tools"></a>

Para acelerar su ciclo de desarrollo, hay una serie de herramientas y técnicas que puede utilizar al probar sus funciones. Por ejemplo, tanto [Accelerate AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/using-sam-cli-sync.html) como el [modo de vigilancia de AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/cli.html#cli-deploy-watch) reducen el tiempo necesario para actualizar los entornos de nube.

La forma en que se define el código de la función de Lambda facilita la adición de pruebas unitarias. Lambda requiere un constructor público sin parámetros para inicializar la clase. La introducción de un segundo constructor interno le permite controlar las dependencias que utiliza su aplicación.

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

Para escribir una prueba para esta función, puede inicializar una nueva instancia de su clase `Function` y pasar una implementación simulada de `IDatabaseRepository`. Los siguientes ejemplos utilizan `XUnit`, `Moq` y `FluentAssertions` para escribir una prueba sencilla que garantice que `FunctionHandler` devuelve un código de estado 200.

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

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

Para ver ejemplos más detallados, incluidos ejemplos de pruebas asincrónicas, consulte el [repositorio de muestras de pruebas .NET](https://github.com/aws-samples/serverless-test-samples/tree/main/dotnet-test-samples) en GitHub.