Referencia para desarrolladores de C# de Azure FunctionsAzure Functions C# developer reference

Este artículo es una introducción al desarrollo de Azure Functions mediante el uso de C# en las bibliotecas de clases .NET.This article is an introduction to developing Azure Functions by using C# in .NET class libraries.

Como desarrollador de C#, puede que también le interese uno de los artículos siguientes:As a C# developer, you may also be interested in one of the following articles:

IntroducciónGetting started ConceptosConcepts Ejemplos o aprendizaje guiadoGuided learning/samples

Azure Functions es compatible con C# y con los lenguajes de programación de scripts de C#.Azure Functions supports C# and C# script programming languages. Si busca orientación sobre cómo usar C# en Azure Portal, vea la referencia para desarrolladores de scripts de C#.If you're looking for guidance on using C# in the Azure portal, see C# script (.csx) developer reference.

Versiones compatiblesSupported versions

Las versiones del entorno en tiempo de ejecución de Functions funcionan con versiones específicas de .NET.Versions of the Functions runtime work with specific versions of .NET. En la tabla siguiente se muestra el nivel más alto de .NET Core y .NET Framework que se puede usar con una versión específica de Functions en el proyecto.The following table shows the highest level of .NET Core and .NET Framework and .NET Core that can be used with a specific version of Functions in your project.

Versiones del entorno en tiempo de ejecución de FunctionsFunctions runtime version Versión máxima de .NETMax .NET version
Functions 3.xFunctions 3.x .NET Core 3.1.NET Core 3.1
Functions 2.xFunctions 2.x .NET Core 2.2.NET Core 2.2
Functions 1.xFunctions 1.x .NET Framework 4.7.NET Framework 4.7

Para obtener más información, consulte Introducción a las versiones de tiempo de ejecución de Azure Functions.To learn more, see Azure Functions runtime versions overview

Proyecto de biblioteca de clases de FunctionsFunctions class library project

En Visual Studio, la plantilla de proyecto de Azure Functions crea un proyecto de biblioteca de clases de C# que contiene los archivos siguientes:In Visual Studio, the Azure Functions project template creates a C# class library project that contains the following files:

Al compilar el proyecto, se genera una estructura de carpetas que se parece al siguiente ejemplo del directorio de salida de la compilación:When you build the project, a folder structure that looks like the following example is generated in the build output directory:

<framework.version>
 | - bin
 | - MyFirstFunction
 | | - function.json
 | - MySecondFunction
 | | - function.json
 | - host.json

Este directorio es lo que se implementa en la aplicación de función en Azure.This directory is what gets deployed to your function app in Azure. Las extensiones de enlace necesarias en la versión 2.x del sistema en tiempo de ejecución de Functions se agregan al proyecto como paquetes de NuGet.The binding extensions required in version 2.x of the Functions runtime are added to the project as NuGet packages.

Importante

El proceso de compilación crea un archivo function.json para cada función.The build process creates a function.json file for each function. Este archivo function.json no está pensado para que se pueda modificar directamente.This function.json file is not meant to be edited directly. No se puede cambiar la configuración del enlace ni deshabilitar la función mediante la edición de este archivo.You can't change binding configuration or disable the function by editing this file. Para obtener información sobre cómo deshabilitar una función, consulte How to disable functions (Cómo deshabilitar funciones).To learn how to disable a function, see How to disable functions.

Métodos reconocidos como funcionesMethods recognized as functions

En una biblioteca de clases, una función es un método estático con un atributo FunctionName y un atributo desencadenador, tal como se muestra en el ejemplo siguiente:In a class library, a function is a static method with a FunctionName and a trigger attribute, as shown in the following example:

public static class SimpleExample
{
    [FunctionName("QueueTrigger")]
    public static void Run(
        [QueueTrigger("myqueue-items")] string myQueueItem, 
        ILogger log)
    {
        log.LogInformation($"C# function processed: {myQueueItem}");
    }
} 

El atributo FunctionName marca el método como punto de entrada de una función.The FunctionName attribute marks the method as a function entry point. El nombre debe ser único dentro de un proyecto, debe empezar por una letra y solo puede incluir letras, números, _ y -, y hasta 127 caracteres.The name must be unique within a project, start with a letter and only contain letters, numbers, _, and -, up to 127 characters in length. Las plantillas de proyecto suelen crear un método denominado Run, pero el nombre de método puede ser cualquier nombre de método de C# válido.Project templates often create a method named Run, but the method name can be any valid C# method name.

El atributo desencadenador especifica el tipo de desencadenador y enlaza los datos de entrada a un parámetro del método.The trigger attribute specifies the trigger type and binds input data to a method parameter. La función de ejemplo se desencadena mediante un mensaje de cola, y este último se pasa al método en el myQueueItem parámetro.The example function is triggered by a queue message, and the queue message is passed to the method in the myQueueItem parameter.

Parámetros de la firma del métodoMethod signature parameters

La firma del método puede contener parámetros distintos del usado con el atributo desencadenador.The method signature may contain parameters other than the one used with the trigger attribute. Estos son algunos de los parámetros adicionales que puede incluir:Here are some of the additional parameters that you can include:

El orden de los parámetros en la signatura de función no es importante.The order of parameters in the function signature does not matter. Por ejemplo, puede colocar los parámetros de desencadenador antes o después de otros enlaces y puede colocar el parámetro de registrador antes o después de los parámetros de desencadenador o enlace.For example, you can put trigger parameters before or after other bindings, and you can put the logger parameter before or after trigger or binding parameters.

Ejemplo de enlace de salidaOutput binding example

En el ejemplo siguiente se modifica el ejemplo anterior mediante la adición de un enlace de la cola de salida.The following example modifies the preceding one by adding an output queue binding. La función escribe el mensaje de la cola que desencadena la función en un nuevo mensaje de cola de una cola distinta.The function writes the queue message that triggers the function to a new queue message in a different queue.

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

En los artículos de referencia de enlace (colas de almacenamiento, por ejemplo) se explica qué tipos de parámetros puede usar con los atributos de enlace de entrada o salida y desencadenador.The binding reference articles (Storage queues, for example) explain which parameter types you can use with trigger, input, or output binding attributes.

Ejemplo de expresiones de enlaceBinding expressions example

El código siguiente recibe el nombre de la cola que se va a supervisar desde una configuración de aplicación y recibe la hora de creación del mensaje de cola en el parámetro insertionTime.The following code gets the name of the queue to monitor from an app setting, and it gets the queue message creation time in the insertionTime parameter.

public static class BindingExpressionsExample
{
    [FunctionName("LogQueueMessage")]
    public static void Run(
        [QueueTrigger("%queueappsetting%")] string myQueueItem,
        DateTimeOffset insertionTime,
        ILogger log)
    {
        log.LogInformation($"Message content: {myQueueItem}");
        log.LogInformation($"Created at: {insertionTime}");
    }
}

Archivo function.json generado automáticamenteAutogenerated function.json

El proceso de compilación crea un archivo function.json en una carpeta de la función en la carpeta de compilación.The build process creates a function.json file in a function folder in the build folder. Como se indicó anteriormente, este archivo no está pensado para que se pueda modificar directamente.As noted earlier, this file is not meant to be edited directly. No se puede cambiar la configuración del enlace ni deshabilitar la función mediante la edición de este archivo.You can't change binding configuration or disable the function by editing this file.

El propósito de este archivo es proporcionar información al controlador de escala que se usará para escalar decisiones en el plan de consumo.The purpose of this file is to provide information to the scale controller to use for scaling decisions on the Consumption plan. Por esta razón, el archivo solo tiene información del desencadenador, no sobre los enlaces de entrada o salida.For this reason, the file only has trigger info, not input or output bindings.

El archivo function.json generado incluye una propiedad configurationSource que indica el tiempo de ejecución para utilizar atributos de .NET para los enlaces, en lugar de la configuración de function.json.The generated function.json file includes a configurationSource property that tells the runtime to use .NET attributes for bindings, rather than function.json configuration. Este es un ejemplo:Here's an example:

{
  "generatedBy": "Microsoft.NET.Sdk.Functions-1.0.0.0",
  "configurationSource": "attributes",
  "bindings": [
    {
      "type": "queueTrigger",
      "queueName": "%input-queue-name%",
      "name": "myQueueItem"
    }
  ],
  "disabled": false,
  "scriptFile": "..\\bin\\FunctionApp1.dll",
  "entryPoint": "FunctionApp1.QueueTrigger.Run"
}

Microsoft.NET.Sdk.FunctionsMicrosoft.NET.Sdk.Functions

El archivo function.json se genera mediante el paquete NuGet Microsoft.NET.Sdk.Functions.The function.json file generation is performed by the NuGet package Microsoft.NET.Sdk.Functions.

Se usa el mismo paquete para las versiones 1.x y 2.x de Functions Runtime.The same package is used for both version 1.x and 2.x of the Functions runtime. La plataforma de destino es lo que diferencia un proyecto 1.x de un proyecto 2.x.The target framework is what differentiates a 1.x project from a 2.x project. Estas son las partes relevantes de los archivos .csproj que muestran distintas plataformas de destino y el mismo paquete Sdk:Here are the relevant parts of .csproj files, showing different target frameworks and the same Sdk package:

<PropertyGroup>
  <TargetFramework>netcoreapp2.1</TargetFramework>
  <AzureFunctionsVersion>v2</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
  <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.8" />
</ItemGroup>

Entre las dependencias del paquete Sdk se encuentran los desencadenadores y los enlaces.Among the Sdk package dependencies are triggers and bindings. Un proyecto 1.x hace referencia a los enlaces y desencadenadores 1.x porque tienen como destino .NET Framework, mientras que los enlaces y desencadenadores 2.x tienen como destino .NET Core.A 1.x project refers to 1.x triggers and bindings because those triggers and bindings target the .NET Framework, while 2.x triggers and bindings target .NET Core.

El Sdk paquete también depende de Newtonsoft.Json e, indirectamente, de WindowsAzure.Storage.The Sdk package also depends on Newtonsoft.Json, and indirectly on WindowsAzure.Storage. Estas dependencias garantizan que el proyecto utiliza las versiones de los paquetes que funcionan con la versión de Functions Runtime que el proyecto tiene como destino.These dependencies make sure that your project uses the versions of those packages that work with the Functions runtime version that the project targets. Por ejemplo, Newtonsoft.Json tiene la versión 11 para .NET Framework 4.6.1, pero la instancia de Functions Runtime que tiene como destino .NET Framework 4.6.1 solo es compatible con Newtonsoft.Json 9.0.1.For example, Newtonsoft.Json has version 11 for .NET Framework 4.6.1, but the Functions runtime that targets .NET Framework 4.6.1 is only compatible with Newtonsoft.Json 9.0.1. Por tanto, el código de función de ese proyecto también tiene que usar Newtonsoft.Json 9.0.1.So your function code in that project also has to use Newtonsoft.Json 9.0.1.

El código fuente de Microsoft.NET.Sdk.Functions está disponible en el repositorio de GitHub azure-functions-vs-build-sdk.The source code for Microsoft.NET.Sdk.Functions is available in the GitHub repo azure-functions-vs-build-sdk.

Versión en tiempo de ejecuciónRuntime version

Visual Studio usa Azure Functions Core Tools para ejecutar proyectos de Functions.Visual Studio uses the Azure Functions Core Tools to run Functions projects. Core Tools es una interfaz de línea de comandos para Functions Runtime.The Core Tools is a command-line interface for the Functions runtime.

Core Tools se instala mediante npm, que no afecta a la versión de Core Tools que Visual Studio utiliza.If you install the Core Tools by using npm, that doesn't affect the Core Tools version used by Visual Studio. Para la versión 1.x de Functions Runtime, Visual Studio almacena Core Tools en %USERPROFILE%\AppData\Local\Azure.Functions.Cli y utiliza la versión más reciente almacenada allí.For the Functions runtime version 1.x, Visual Studio stores Core Tools versions in %USERPROFILE%\AppData\Local\Azure.Functions.Cli and uses the latest version stored there. Para Functions 2.x, Core Tools se incluye en la extensión Azure Functions and Web Jobs Tools.For Functions 2.x, the Core Tools are included in the Azure Functions and Web Jobs Tools extension. Para 1.x y 2.x, puede ver qué versión se usa en la salida de la consola cuando se ejecuta un proyecto de Functions:For both 1.x and 2.x, you can see what version is being used in the console output when you run a Functions project:

[3/1/2018 9:59:53 AM] Starting Host (HostId=contoso2-1518597420, Version=2.0.11353.0, ProcessId=22020, Debug=False, Attempt=0, FunctionsExtensionVersion=)

ReadyToRunReadyToRun

La aplicación de funciones se puede compilar como archivos binarios de ReadyToRun.You can compile your function app as ReadyToRun binaries. ReadyToRun es una forma de compilación Ahead Of Time que puede mejorar el rendimiento de inicio para ayudar a reducir el impacto del inicio en frío cuando se ejecuta en un plan de consumo.ReadyToRun is a form of ahead-of-time compilation that can improve startup performance to help reduce the impact of cold-start when running in a Consumption plan.

ReadyToRun está disponible en .NET 3.0 y requiere la versión 3.0 del runtime de Azure Functions.ReadyToRun is available in .NET 3.0 and requires version 3.0 of the Azure Functions runtime.

Para compilar un proyecto como ReadyToRun, actualice el archivo del proyecto agregando los elementos <PublishReadyToRun> y <RuntimeIdentifier>.To compile your project as ReadyToRun, update your project file by adding the <PublishReadyToRun> and <RuntimeIdentifier> elements. A continuación se encuentra la configuración para publicar en una aplicación de funciones de Windows de 32 bits.The following is the configuration for publishing to a Windows 32-bit function app.

<PropertyGroup>
  <TargetFramework>netcoreapp3.1</TargetFramework>
  <AzureFunctionsVersion>v3</AzureFunctionsVersion>
  <PublishReadyToRun>true</PublishReadyToRun>
  <RuntimeIdentifier>win-x86</RuntimeIdentifier>
</PropertyGroup>

Importante

Actualmente, ReadyToRun no admite la compilación cruzada.ReadyToRun currently doesn't support cross-compilation. Debe compilar la aplicación en la misma plataforma que el destino de implementación.You must build your app on the same platform as the deployment target. Preste también atención al "valor de bits" que está configurado en la aplicación de funciones.Also, pay attention to the "bitness" that is configured in your function app. Por ejemplo, si la aplicación de funciones de Azure es Windows de 64 bits, debe compilarla en Windows con win-x64 como identificador de runtime.For example, if your function app in Azure is Windows 64-bit, you must compile your app on Windows with win-x64 as the runtime identifier.

La aplicación también se puede compilar con ReadyToRun desde la línea de comandos.You can also build your app with ReadyToRun from the command line. Para más información, consulte la opción -p:PublishReadyToRun=true en dotnet publish.For more information, see the -p:PublishReadyToRun=true option in dotnet publish.

Tipos compatibles para los enlacesSupported types for bindings

Cada enlace tiene sus propios tipos compatibles; por ejemplo, un atributo desencadenador de blobs puede aplicarse a un parámetro de cadena, un parámetro POCO, un parámetro CloudBlockBlob o cualquiera de los demás tipos compatibles.Each binding has its own supported types; for instance, a blob trigger attribute can be applied to a string parameter, a POCO parameter, a CloudBlockBlob parameter, or any of several other supported types. En el artículo de referencia sobre los enlaces de blobs se enumeran todos los tipos de parámetros compatibles.The binding reference article for blob bindings lists all supported parameter types. Para obtener más información, vea el artículo sobre desencadenadores y enlaces y los documentos de referencia sobre enlaces para cada tipo de enlace.For more information, see Triggers and bindings and the binding reference docs for each binding type.

Sugerencia

Si planea usar los enlaces HTTP o WebHook, debe evitar el agotamiento de puertos que puede deberse a la creación incorrecta de instancias de HttpClient.If you plan to use the HTTP or WebHook bindings, plan to avoid port exhaustion that can be caused by improper instantiation of HttpClient. Para más información, consulte How to manage connections in Azure Functions (Administración de conexiones en Azure Functions).For more information, see How to manage connections in Azure Functions.

Enlace al valor devuelto del métodoBinding to method return value

Puede usar un valor devuelto de método para un enlace de salida mediante la aplicación del atributo al valor devuelto de método.You can use a method return value for an output binding, by applying the attribute to the method return value. Para ver ejemplos, consulte Desencadenadores y enlaces.For examples, see Triggers and bindings.

Utilice el valor devuelto solo si una ejecución de función correcta siempre da como resultado un valor devuelto para pasar al enlace de salida.Use the return value only if a successful function execution always results in a return value to pass to the output binding. En caso contrario, use ICollector o IAsyncCollector, como se muestra en la sección siguiente.Otherwise, use ICollector or IAsyncCollector, as shown in the following section.

Escribir varios valores de salidaWriting multiple output values

Para escribir varios valores en un enlace de salida, o si una invocación de función correcta podría no dar nada como resultado para pasar al enlace de salida, use los tipos ICollector o IAsyncCollector.To write multiple values to an output binding, or if a successful function invocation might not result in anything to pass to the output binding, use the ICollector or IAsyncCollector types. Estos tipos son colecciones de solo escritura que se escriben en el enlace de salida cuando se completa el método.These types are write-only collections that are written to the output binding when the method completes.

En este ejemplo se escriben varios mensajes en cola en la misma cola mediante ICollector:This example writes multiple queue messages into the same queue using ICollector:

public static class ICollectorExample
{
    [FunctionName("CopyQueueMessageICollector")]
    public static void Run(
        [QueueTrigger("myqueue-items-source-3")] string myQueueItem,
        [Queue("myqueue-items-destination")] ICollector<string> myDestinationQueue,
        ILogger log)
    {
        log.LogInformation($"C# function processed: {myQueueItem}");
        myDestinationQueue.Add($"Copy 1: {myQueueItem}");
        myDestinationQueue.Add($"Copy 2: {myQueueItem}");
    }
}

AsyncAsync

Para convertir una función en asincrónica, use la palabra clave async y devuelva un objeto Task.To make a function asynchronous, use the async keyword and return a Task object.

public static class AsyncExample
{
    [FunctionName("BlobCopy")]
    public static async Task RunAsync(
        [BlobTrigger("sample-images/{blobName}")] Stream blobInput,
        [Blob("sample-images-copies/{blobName}", FileAccess.Write)] Stream blobOutput,
        CancellationToken token,
        ILogger log)
    {
        log.LogInformation($"BlobCopy function processed.");
        await blobInput.CopyToAsync(blobOutput, 4096, token);
    }
}

No puede usar parámetros out en funciones asincrónicas.You can't use out parameters in async functions. Para los enlaces de salida, utilice el valor devuelto de función o un objeto recopilador en su lugar.For output bindings, use the function return value or a collector object instead.

Tokens de cancelaciónCancellation tokens

Una función puede aceptar un parámetro CancellationToken que permite que el sistema operativo notifique al código cuando la función esté a punto de finalizar.A function can accept a CancellationToken parameter, which enables the operating system to notify your code when the function is about to be terminated. Puede utilizar esta notificación para asegurarse de que la función no se termina inesperadamente en una forma que deje los datos en un estado incoherente.You can use this notification to make sure the function doesn't terminate unexpectedly in a way that leaves data in an inconsistent state.

En el ejemplo siguiente se muestra cómo comprobar la finalización inminente de la función.The following example shows how to check for impending function termination.

public static class CancellationTokenExample
{
    public static void Run(
        [QueueTrigger("inputqueue")] string inputText,
        TextWriter logger,
        CancellationToken token)
    {
        for (int i = 0; i < 100; i++)
        {
            if (token.IsCancellationRequested)
            {
                logger.WriteLine("Function was cancelled at iteration {0}", i);
                break;
            }
            Thread.Sleep(5000);
            logger.WriteLine("Normal processing for queue message={0}", inputText);
        }
    }
}

RegistroLogging

En el código de función, puede escribir la salida de los registros que aparecen como seguimientos de Application Insights.In your function code, you can write output to logs that appear as traces in Application Insights. La manera recomendada de escribir en los registros es incluir un parámetro de tipo ILogger, que normalmente se denomina log.The recommended way to write to the logs is to include a parameter of type ILogger, which is typically named log. Versión 1.x del entorno de ejecución de Functions usado TraceWriter, que también escribe en Application Insights, pero no admite el registro estructurado.Version 1.x of the Functions runtime used TraceWriter, which also writes to Application Insights, but doesn't support structured logging. No use Console.Write para escribir los registros, ya que Application Insights no captura los datos.Don't use Console.Write to write your logs, since this data isn't captured by Application Insights.

ILoggerILogger

En la definición de la función, incluya un parámetro ILogger, que admite el registro estructurado.In your function definition, include an ILogger parameter, which supports structured logging.

Con un objeto ILogger, llamará a los métodos de extensión en ILogger Log<level> para crear registros.With an ILogger object, you call Log<level> extension methods on ILogger to create logs. El código siguiente escribe registros Information con la categoría Function.<YOUR_FUNCTION_NAME>.User.:The following code writes Information logs with category Function.<YOUR_FUNCTION_NAME>.User.:

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, ILogger logger)
{
    logger.LogInformation("Request for item with key={itemKey}.", id);

Registro estructuradoStructured logging

El orden de los marcadores de posición, no sus nombres, determina qué parámetros se usan en el mensaje del registro.The order of placeholders, not their names, determines which parameters are used in the log message. Supongamos que tiene el siguiente código:Suppose you have the following code:

string partitionKey = "partitionKey";
string rowKey = "rowKey";
logger.LogInformation("partitionKey={partitionKey}, rowKey={rowKey}", partitionKey, rowKey);

Si mantiene la misma cadena de mensaje e invierte el orden de los parámetros, el texto del mensaje resultante tendrá los valores en los lugares incorrectos.If you keep the same message string and reverse the order of the parameters, the resulting message text would have the values in the wrong places.

Los marcadores de posición se controlan de esta forma para que pueda hacer el registro estructurado.Placeholders are handled this way so that you can do structured logging. Application Insights almacena los pares de nombre-valor del parámetro y la cadena de mensaje.Application Insights stores the parameter name-value pairs and the message string. Como resultado, los argumentos del mensaje se convierten en campos que puede consultar.The result is that the message arguments become fields that you can query on.

Si la llamada de método del registrador tiene un aspecto similar al ejemplo anterior, puede consultar el campo customDimensions.prop__rowKey.If your logger method call looks like the previous example, you can query the field customDimensions.prop__rowKey. Se agrega el prefijo prop__ para asegurar que no haya ninguna colisión entre los campos que agrega el tiempo de ejecución y los campos que agrega el código de la función.The prop__ prefix is added to ensure there are no collisions between fields the runtime adds and fields your function code adds.

También puede consultar la cadena del mensaje original haciendo referencia al campo customDimensions.prop__{OriginalFormat}.You can also query on the original message string by referencing the field customDimensions.prop__{OriginalFormat}.

Esta es una representación de JSON de ejemplo de los datos customDimensions:Here's a sample JSON representation of customDimensions data:

{
  "customDimensions": {
    "prop__{OriginalFormat}":"C# Queue trigger function processed: {message}",
    "Category":"Function",
    "LogLevel":"Information",
    "prop__message":"c9519cbf-b1e6-4b9b-bf24-cb7d10b1bb89"
  }
}

Registrar telemetría personalizada en funciones de C#Log custom telemetry in C# functions

Hay una versión específica de funciones del SDK de Application Insights que puede usar para enviar datos de telemetría personalizados desde las funciones a Application Insights: Microsoft.Azure.WebJobs.Logging.ApplicationInsights.There is a Functions-specific version of the Application Insights SDK that you can use to send custom telemetry data from your functions to Application Insights: Microsoft.Azure.WebJobs.Logging.ApplicationInsights. Use el comando siguiente desde el símbolo del sistema para instalar este paquete:Use the following command from the command prompt to install this package:

dotnet add package Microsoft.Azure.WebJobs.Logging.ApplicationInsights --version <VERSION>

En este comando, reemplace <VERSION> por una versión de este paquete que admita la versión instalada de Microsoft.Azure.WebJobs.In this command, replace <VERSION> with a version of this package that supports your installed version of Microsoft.Azure.WebJobs.

En el siguiente ejemplo de C# se usa la API de telemetría personalizada.The following C# examples uses the custom telemetry API. El ejemplo es para una biblioteca de clases. NET, pero el código de Application Insights es el mismo para la secuencia de comandos de C#.The example is for a .NET class library, but the Application Insights code is the same for C# script.

La versión 2.x y versiones posteriores del entorno de ejecución utilizan las características más recientes de Application Insights para correlacionar automáticamente la telemetría con la operación actual.Version 2.x and later versions of the runtime use newer features in Application Insights to automatically correlate telemetry with the current operation. No es necesario establecer manualmente los campos de operación Id, ParentId o Name.There's no need to manually set the operation Id, ParentId, or Name fields.

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

using Microsoft.ApplicationInsights;
using Microsoft.ApplicationInsights.DataContracts;
using Microsoft.ApplicationInsights.Extensibility;
using System.Linq;

namespace functionapp0915
{
    public class HttpTrigger2
    {
        private readonly TelemetryClient telemetryClient;

        /// Using dependency injection will guarantee that you use the same configuration for telemetry collected automatically and manually.
        public HttpTrigger2(TelemetryConfiguration telemetryConfiguration)
        {
            this.telemetryClient = new TelemetryClient(telemetryConfiguration);
        }

        [FunctionName("HttpTrigger2")]
        public Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)]
            HttpRequest req, ExecutionContext context, ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");
            DateTime start = DateTime.UtcNow;

            // Parse query parameter
            string name = req.Query
                .FirstOrDefault(q => string.Compare(q.Key, "name", true) == 0)
                .Value;

            // Write an event to the customEvents table.
            var evt = new EventTelemetry("Function called");
            evt.Context.User.Id = name;
            this.telemetryClient.TrackEvent(evt);

            // Generate a custom metric, in this case let's use ContentLength.
            this.telemetryClient.GetMetric("contentLength").TrackValue(req.ContentLength);

            // Log a custom dependency in the dependencies table.
            var dependency = new DependencyTelemetry
            {
                Name = "GET api/planets/1/",
                Target = "swapi.co",
                Data = "https://swapi.co/api/planets/1/",
                Timestamp = start,
                Duration = DateTime.UtcNow - start,
                Success = true
            };
            dependency.Context.User.Id = name;
            this.telemetryClient.TrackDependency(dependency);

            return Task.FromResult<IActionResult>(new OkResult());
        }
    }
}

En este ejemplo, el host agrega los datos de métricas personalizados antes de enviarlos a la tabla customMetrics.In this example, the custom metric data gets aggregated by the host before being sent to the customMetrics table. Para obtener más información, consulte la documentación de GetMetric en Application Insights.To learn more, see the GetMetric documentation in Application Insights.

Cuando se ejecuta localmente, debe agregar el valor APPINSIGHTS_INSTRUMENTATIONKEY, con la clave de Application Insights, al archivo local.settings.json.When running locally, you must add the APPINSIGHTS_INSTRUMENTATIONKEY setting, with the Application Insights key, to the local.settings.json file.

No llame a TrackRequest ni a StartOperation<RequestTelemetry>, ya que verá solicitudes duplicadas de invocaciones de función.Don't call TrackRequest or StartOperation<RequestTelemetry> because you'll see duplicate requests for a function invocation. El tiempo de ejecución de Functions realiza un seguimiento automático de las solicitudes.The Functions runtime automatically tracks requests.

No establezca telemetryClient.Context.Operation.Id.Don't set telemetryClient.Context.Operation.Id. Esta configuración global provoca una correlación incorrecta cuando muchas funciones se ejecuten de manera simultánea.This global setting causes incorrect correlation when many functions are running simultaneously. En su lugar, cree una instancia de telemetría nueva (DependencyTelemetry, EventTelemetry) y modifique su propiedad Context.Instead, create a new telemetry instance (DependencyTelemetry, EventTelemetry) and modify its Context property. Luego, pase la instancia de telemetría al método Track correspondiente en TelemetryClient (TrackDependency(), TrackEvent(), TrackMetric()).Then pass in the telemetry instance to the corresponding Track method on TelemetryClient (TrackDependency(), TrackEvent(), TrackMetric()). Este método garantiza que la telemetría tenga los detalles de correlación correctos para la invocación actual de la función.This method ensures that the telemetry has the correct correlation details for the current function invocation.

Variables de entornoEnvironment variables

Para obtener una variable de entorno o un valor de configuración de aplicación, use System.Environment.GetEnvironmentVariable, como se muestra en el ejemplo de código siguiente:To get an environment variable or an app setting value, use System.Environment.GetEnvironmentVariable, as shown in the following code example:

public static class EnvironmentVariablesExample
{
    [FunctionName("GetEnvironmentVariables")]
    public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
    {
        log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
        log.LogInformation(GetEnvironmentVariable("AzureWebJobsStorage"));
        log.LogInformation(GetEnvironmentVariable("WEBSITE_SITE_NAME"));
    }

    public static string GetEnvironmentVariable(string name)
    {
        return name + ": " +
            System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
    }
}

La configuración de la aplicación se puede leer de las variables de entorno tanto cuando se desarrolla de manera local como cuando se ejecuta en Azure.App settings can be read from environment variables both when developing locally and when running in Azure. Cuando se desarrolla de manera local, la configuración de la aplicación procede de la colección Values en el archivo local.settings.json.When developing locally, app settings come from the Values collection in the local.settings.json file. En ambos entornos, tanto local como Azure, GetEnvironmentVariable("<app setting name>") recupera el valor de la configuración de aplicación con nombre.In both environments, local and Azure, GetEnvironmentVariable("<app setting name>") retrieves the value of the named app setting. Por ejemplo, cuando se ejecuta de manera local, se devolvería "My Site Name" si el archivo local.settings.json contiene { "Values": { "WEBSITE_SITE_NAME": "My Site Name" } }.For instance, when you're running locally, "My Site Name" would be returned if your local.settings.json file contains { "Values": { "WEBSITE_SITE_NAME": "My Site Name" } }.

La propiedad System.Configuration.ConfigurationManager.AppSettings es una API alternativa para obtener los valores de configuración de la aplicación, pero se recomienda que use GetEnvironmentVariable como se muestra aquí.The System.Configuration.ConfigurationManager.AppSettings property is an alternative API for getting app setting values, but we recommend that you use GetEnvironmentVariable as shown here.

Enlace en tiempo de ejecuciónBinding at runtime

En C# y otros lenguajes .NET, puede usar un patrón de enlace imperativo, en contraposición a los enlaces declarativos de los atributos.In C# and other .NET languages, you can use an imperative binding pattern, as opposed to the declarative bindings in attributes. Los enlaces imperativos resultan útiles cuando los parámetros de enlace tienen que calcularse en tiempo de ejecución, en lugar de en el tiempo de diseño.Imperative binding is useful when binding parameters need to be computed at runtime rather than design time. Con este patrón, se pueden establecer enlaces compatibles de entrada y salida sobre la marcha en el código de función.With this pattern, you can bind to supported input and output bindings on-the-fly in your function code.

Defina un enlace imperativo como se indica a continuación:Define an imperative binding as follows:

  • No incluya un atributo en la signatura de función para los enlaces imperativos deseados.Do not include an attribute in the function signature for your desired imperative bindings.

  • Pase un parámetro de entrada Binder binder o IBinder binder.Pass in an input parameter Binder binder or IBinder binder.

  • Utilice el siguiente patrón de C# para realizar el enlace de datos.Use the following C# pattern to perform the data binding.

    using (var output = await binder.BindAsync<T>(new BindingTypeAttribute(...)))
    {
        ...
    }
    

    BindingTypeAttribute es el atributo de .NET que define el enlace y T es un tipo de entrada o de salida compatible con ese tipo de enlace.BindingTypeAttribute is the .NET attribute that defines your binding, and T is an input or output type that's supported by that binding type. T no puede ser un tipo de parámetro out (como out JObject).T cannot be an out parameter type (such as out JObject). Por ejemplo, el enlace de salida de la tabla de Mobile Apps admite seis tipos de salida, pero solo se puede utilizar ICollector<T> o IAsyncCollector<T> con el enlace imperativo.For example, the Mobile Apps table output binding supports six output types, but you can only use ICollector<T> or IAsyncCollector<T> with imperative binding.

Ejemplo de un único atributoSingle attribute example

El ejemplo de código siguiente crea un enlace de salida al blob de almacenamiento con la ruta de acceso al blob definida en tiempo de ejecución y, a continuación, escribe una cadena en el blob.The following example code creates a Storage blob output binding with blob path that's defined at run time, then writes a string to the blob.

public static class IBinderExample
{
    [FunctionName("CreateBlobUsingBinder")]
    public static void Run(
        [QueueTrigger("myqueue-items-source-4")] string myQueueItem,
        IBinder binder,
        ILogger log)
    {
        log.LogInformation($"CreateBlobUsingBinder function processed: {myQueueItem}");
        using (var writer = binder.Bind<TextWriter>(new BlobAttribute(
                    $"samples-output/{myQueueItem}", FileAccess.Write)))
        {
            writer.Write("Hello World!");
        };
    }
}

BlobAttribute define el enlace de entrada o salida del blob de almacenamiento, y TextWriter es un tipo de enlace de salida admitido.BlobAttribute defines the Storage blob input or output binding, and TextWriter is a supported output binding type.

Ejemplo de varios atributosMultiple attribute example

En el ejemplo anterior se obtiene el valor de la aplicación para la cadena de conexión en la cuenta de almacenamiento principal de la aplicación de función (que es AzureWebJobsStorage).The preceding example gets the app setting for the function app's main Storage account connection string (which is AzureWebJobsStorage). Se puede especificar una configuración personalizada de la aplicación para utilizarla para la cuenta de almacenamiento agregando el atributo StorageAccountAttribute y pasando la matriz de atributos a BindAsync<T>().You can specify a custom app setting to use for the Storage account by adding the StorageAccountAttribute and passing the attribute array into BindAsync<T>(). Use un parámetro Binder, no IBinder.Use a Binder parameter, not IBinder. Por ejemplo:For example:

public static class IBinderExampleMultipleAttributes
{
    [FunctionName("CreateBlobInDifferentStorageAccount")]
    public async static Task RunAsync(
            [QueueTrigger("myqueue-items-source-binder2")] string myQueueItem,
            Binder binder,
            ILogger log)
    {
        log.LogInformation($"CreateBlobInDifferentStorageAccount function processed: {myQueueItem}");
        var attributes = new Attribute[]
        {
        new BlobAttribute($"samples-output/{myQueueItem}", FileAccess.Write),
        new StorageAccountAttribute("MyStorageAccount")
        };
        using (var writer = await binder.BindAsync<TextWriter>(attributes))
        {
            await writer.WriteAsync("Hello World!!");
        }
    }
}

Desencadenadores y enlacesTriggers and bindings

En esta tabla se muestran los enlaces que son compatibles con las versiones principales del entorno en tiempo de ejecución de Azure Functions:This table shows the bindings that are supported in the major versions of the Azure Functions runtime:

TipoType 1.x1.x 2.x y posteriores12.x and higher1 DesencadenadorTrigger EntradaInput OutputOutput
Blob StorageBlob storage
Azure Cosmos DBAzure Cosmos DB
Dapr3Dapr3
Event GridEvent Grid
Event HubsEvent Hubs
HTTP y webhooksHTTP & webhooks
IoT HubIoT Hub
Kafka2Kafka2
Mobile AppsMobile Apps
Centros de notificacionesNotification Hubs
Queue StorageQueue storage
RabbitMQ2RabbitMQ2
SendGridSendGrid
Service BusService Bus
SignalRSignalR
Table storageTable storage
TemporizadorTimer
TwilioTwilio

1 A partir del entorno en tiempo de ejecución de la versión 2.x, se deben registrar todos los enlaces, excepto HTTP y el temporizador.1 Starting with the version 2.x runtime, all bindings except HTTP and Timer must be registered. Consulte Registro de extensiones de enlace.See Register binding extensions.

2 Los desencadenadores no se admiten en el plan de consumo.2 Triggers aren't supported in the Consumption plan. Requiere desencadenadores controlados por el runtime.Requires runtime-driven triggers.

3 Solo se admite en Kubernetes, IoT Edge y otros modos autohospedados.3 Supported only in Kubernetes, IoT Edge, and other self-hosted modes only.

Pasos siguientesNext steps