Referencia para desarrolladores de scripts de C# de Azure Functions (.csx)
Este artículo es una introducción al desarrollo de Azure Functions mediante el uso de scripts de C# ( .csx).
Importante
El script de C# se admite principalmente para proporcionar una experiencia cómoda en el portal para ayudarle a empezar a crear y ejecutar rápidamente funciones de C#. En el caso de las aplicaciones de calidad de producción, en su lugar debe desarrollar las funciones de C# localmente como un proyecto de biblioteca de clases de C# compilado. Para obtener información sobre cómo migrar un proyecto de script de C# a un proyecto de biblioteca de clases de C# (trabajo aislado), consulte Conversión de una aplicación de script de C# en un proyecto de C#.
Azure Functions permite desarrollar funciones con C# de una de las siguientes maneras:
Tipo | Proceso de ejecución | Extensión de código | Entorno de desarrollo | Referencia |
---|---|---|---|---|
Script de C# | en el mismo proceso | .csx | Portal Core Tools |
Este artículo |
Biblioteca de clases de C# (trabajo aislados) | proceso de trabajo aislado | .cs | Visual Studio Visual Studio Code Core Tools |
Funciones de proceso de trabajo aislado de .NET |
Biblioteca de clases de C# (en curso) | en el mismo proceso | .cs | Visual Studio Visual Studio Code Core Tools |
Funciones de biblioteca de clases de C# en proceso |
Funcionamiento de .csx
Los datos fluyen en la función de C# a través de los argumentos de método. Los nombres de los argumentos se especifican en un archivo function.json
, y hay nombres predefinidos para acceder a cosas como el registrador de funciones y los tokens de cancelación.
El formato .csx permite escribir menos "texto reutilizable" y centrarse en escribir solo una función de C#. En lugar de encapsular todo en un espacio de nombres y una clase, defina solamente un método Run
. Incluya las referencias a ensamblados y los espacios de nombres al principio del archivo como de costumbre.
Los archivos .csx de una aplicación de función se compilan cuando se inicializa una instancia. Este paso de compilación puede conllevar, por ejemplo, que un arranque en frío pueda tardar más para las funciones de script de C# en comparación con las bibliotecas de clases de C#. En este paso de compilación también se plantea la pregunta de por qué las funciones de script de C# se pueden editar en Azure Portal y las bibliotecas de clases de C# no.
Estructura de carpetas
La estructura de carpetas para un proyecto de script de C# tiene el siguiente aspecto:
FunctionsProject
| - MyFirstFunction
| | - run.csx
| | - function.json
| | - function.proj
| - MySecondFunction
| | - run.csx
| | - function.json
| | - function.proj
| - host.json
| - extensions.csproj
| - bin
Hay un archivo host.json compartido que se puede usar para configurar la aplicación de función. Cada función tiene su propio archivo de código (.csx) y archivo de configuración de enlace (function.json).
Las extensiones de enlace necesarias en la versión 2.x y posteriores del entorno en tiempo de ejecución de Functions se definen en el archivo extensions.csproj
, con los archivos de biblioteca reales de la carpeta bin
. Al desarrollar de forma local, debe registrar las extensiones de enlace. Al desarrollar funciones en Azure Portal, este registro se realiza automáticamente.
Enlace a argumentos
Los datos de entrada o salida está enlazados a un parámetro de función de script de C# mediante la propiedad name
en el archivo de configuración function.json. En el siguiente ejemplo se muestra un archivo function.json y otro run.csx para una función desencadenada por la cola. El parámetro que recibe los datos del mensaje de cola se llama myQueueItem
porque ese es el valor de la propiedad name
.
{
"disabled": false,
"bindings": [
{
"type": "queueTrigger",
"direction": "in",
"name": "myQueueItem",
"queueName": "myqueue-items",
"connection":"MyStorageConnectionAppSetting"
}
]
}
#r "Microsoft.WindowsAzure.Storage"
using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage.Queue;
using System;
public static void Run(CloudQueueMessage myQueueItem, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem.AsString}");
}
La instrucción #r
se explica más adelante en este artículo.
Tipos compatibles para los enlaces
Cada enlace tiene sus propios tipos compatibles; por ejemplo, se puede utilizar un desencadenador de blobs con un parámetro de cadena, un parámetro POCO, un parámetro CloudBlockBlob
o cualquiera de los demás tipos compatibles. En el artículo de referencia sobre los enlaces de blobs se enumeran todos los tipos de parámetros compatibles para los desencadenadores de blobs. 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.
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
. Para más información, consulte How to manage connections in Azure Functions (Administración de conexiones en Azure Functions).
Referencia a clases personalizadas
Si tiene que utilizar una clase objeto CRL estándar (POCO) personalizada, puede incluir la definición de clase en el mismo archivo o colocarla en un archivo independiente.
En el ejemplo siguiente se muestra un ejemplo de run.csx que incluye una definición de clase POCO.
public static void Run(string myBlob, out MyClass myQueueItem)
{
log.Verbose($"C# Blob trigger function processed: {myBlob}");
myQueueItem = new MyClass() { Id = "myid" };
}
public class MyClass
{
public string Id { get; set; }
}
Una clase POCO debe tener un captador y un establecedor definidos para cada propiedad.
Reutilización del código .csx
Puede usar las clases y los métodos definidos en otros archivos .csx con el archivo run.csx. Para ello, utilice directivas #load
en el archivo run.csx. En el siguiente ejemplo, una rutina de registro denominada MyLogger
se comparte en myLogger.csx y se carga en run.csx mediante la directiva #load
:
Archivo run.csxde ejemplo:
#load "mylogger.csx"
using Microsoft.Extensions.Logging;
public static void Run(TimerInfo myTimer, ILogger log)
{
log.LogInformation($"Log by run.csx: {DateTime.Now}");
MyLogger(log, $"Log by MyLogger: {DateTime.Now}");
}
Archivo mylogger.csxde ejemplo:
public static void MyLogger(ILogger log, string logtext)
{
log.LogInformation(logtext);
}
El uso de un archivo .csx compartido es un patrón común para asignar rigurosamente los datos transferidos entre funciones mediante un objeto POCO. En el siguiente ejemplo simplificado, un desencadenador HTTP y un desencadenador de cola comparten un objeto POCO denominado Order
para tipar fuertemente los datos del pedido:
Por ejemplo, run.csx para el desencadenador HTTP:
#load "..\shared\order.csx"
using System.Net;
using Microsoft.Extensions.Logging;
public static async Task<HttpResponseMessage> Run(Order req, IAsyncCollector<Order> outputQueueItem, ILogger log)
{
log.LogInformation("C# HTTP trigger function received an order.");
log.LogInformation(req.ToString());
log.LogInformation("Submitting to processing queue.");
if (req.orderId == null)
{
return new HttpResponseMessage(HttpStatusCode.BadRequest);
}
else
{
await outputQueueItem.AddAsync(req);
return new HttpResponseMessage(HttpStatusCode.OK);
}
}
Por ejemplo, run.csx para el desencadenador de cola:
#load "..\shared\order.csx"
using System;
using Microsoft.Extensions.Logging;
public static void Run(Order myQueueItem, out Order outputQueueItem, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed order...");
log.LogInformation(myQueueItem.ToString());
outputQueueItem = myQueueItem;
}
Por ejemplo, order.csx:
public class Order
{
public string orderId {get; set; }
public string custName {get; set;}
public string custAddress {get; set;}
public string custEmail {get; set;}
public string cartId {get; set; }
public override String ToString()
{
return "\n{\n\torderId : " + orderId +
"\n\tcustName : " + custName +
"\n\tcustAddress : " + custAddress +
"\n\tcustEmail : " + custEmail +
"\n\tcartId : " + cartId + "\n}";
}
}
Puede usar una ruta de acceso relativa con la directiva #load
:
#load "mylogger.csx"
carga un archivo que se encuentra en la carpeta de la función.#load "loadedfiles\mylogger.csx"
carga un archivo ubicado en una carpeta dentro de la carpeta de la función.#load "..\shared\mylogger.csx"
carga un archivo ubicado en una carpeta del mismo nivel que la carpeta de la función, es decir, directamente en wwwroot.
La directiva #load
solo funciona con archivos .csx, no con archivos .cs.
Enlace al valor devuelto del método
Puede usar el valor devuelto de un método para un enlace de salida, mediante el nombre $return
en function.json.
{
"name": "$return",
"type": "blob",
"direction": "out",
"path": "output-container/{id}"
}
Este es el código de script de C# que usa el valor devuelto, seguido de un ejemplo asincrónico:
public static string Run(WorkItem input, ILogger log)
{
string json = string.Format("{{ \"id\": \"{0}\" }}", input.Id);
log.LogInformation($"C# script processed queue message. Item={json}");
return json;
}
public static Task<string> Run(WorkItem input, ILogger log)
{
string json = string.Format("{{ \"id\": \"{0}\" }}", input.Id);
log.LogInformation($"C# script processed queue message. Item={json}");
return Task.FromResult(json);
}
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. En caso contrario, use ICollector
o IAsyncCollector
, como se muestra en la sección siguiente.
Escribir varios valores de salida
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
. Estos tipos son colecciones de solo escritura que se escriben en el enlace de salida cuando se completa el método.
En este ejemplo se escriben varios mensajes en cola en la misma cola mediante ICollector
:
public static void Run(ICollector<string> myQueue, ILogger log)
{
myQueue.Add("Hello");
myQueue.Add("World!");
}
Registro
Para grabar la salida en los registros de streaming de C#, incluya un argumento de tipo ILogger. Es recomendable que lo denomine log
. Evite el uso de Console.Write
en Azure Functions.
public static void Run(string myBlob, ILogger log)
{
log.LogInformation($"C# Blob trigger function processed: {myBlob}");
}
Nota
Para obtener información sobre un marco de registro más reciente que se pueda usar en lugar de TraceWriter
, vea la documentación de ILogger en la guía para desarrolladores de la biblioteca de clases .NET.
Registro de métricas personalizadas
Puede usar el método de extensión LogMetric
en ILogger
para crear métricas personalizadas en Application Insights. Este es un ejemplo de una llamada de método:
logger.LogMetric("TestMetric", 1234);
Este código es una alternativa a llamar a TrackMetric
con la API de Application Insights para .NET.
Async
Para convertir una función en asincrónica, use la palabra clave async
y devuelva un objeto Task
.
public async static Task ProcessQueueMessageAsync(
string blobName,
Stream blobInput,
Stream blobOutput)
{
await blobInput.CopyToAsync(blobOutput, 4096);
}
No puede usar parámetros out
en funciones asincrónicas. Para los enlaces de salida, utilice el valor devuelto de función o un objeto recopilador en su lugar.
Tokens de cancelación
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. 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.
En el ejemplo siguiente se muestra cómo comprobar la finalización inminente de la función.
using System;
using System.IO;
using System.Threading;
public static void Run(
string inputText,
TextWriter logger,
CancellationToken token)
{
for (int i = 0; i < 100; i++)
{
if (token.IsCancellationRequested)
{
logger.WriteLine("Function was cancelled at iteration {0}", i);
break;
}
Thread.Sleep(5000);
logger.WriteLine("Normal processing for queue message={0}", inputText);
}
}
Importación de espacios de nombres
Si necesita importar espacios de nombres, puede hacerlo de la manera habitual, con la cláusula using
.
using System.Net;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
public static Task<HttpResponseMessage> Run(HttpRequestMessage req, ILogger log)
Los siguientes espacios de nombres se importan automáticamente y, por tanto, son opcionales:
System
System.Collections.Generic
System.IO
System.Linq
System.Net.Http
System.Threading.Tasks
Microsoft.Azure.WebJobs
Microsoft.Azure.WebJobs.Host
Referencia a ensamblados externos
Para los ensamblados de marco, agregue referencias mediante la directiva #r "AssemblyName"
.
#r "System.Web.Http"
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
public static Task<HttpResponseMessage> Run(HttpRequestMessage req, ILogger log)
El entorno de hospedaje de Azure Functions agrega automáticamente los siguientes ensamblados:
mscorlib
System
System.Core
System.Xml
System.Net.Http
Microsoft.Azure.WebJobs
Microsoft.Azure.WebJobs.Host
Microsoft.Azure.WebJobs.Extensions
System.Web.Http
System.Net.Http.Formatting
Se puede hacer referencia a los ensamblados siguientes con nombre simple por versión de runtime:
Newtonsoft.Json
Microsoft.WindowsAzure.Storage
*
*Eliminado en la versión 4.x de runtime.
En el código, se hace referencia a los ensamblados como en el ejemplo siguiente:
#r "AssemblyName"
Hacer referencia a ensamblados personalizados
Para hacer referencia a un ensamblado personalizado, puede usar un ensamblado compartido o un ensamblado privado:
Los ensamblados compartidos se comparten en todas las funciones dentro de una aplicación de función. Para hacer referencia a un ensamblado personalizado, cargue el ensamblado en una carpeta denominada
bin
en la carpeta raíz (wwwroot) de su aplicación de funciones.Los ensamblados privados forman parte del contexto de una función determinada y admiten la instalación de prueba de versiones diferentes. Los ensamblados privados se deben cargar en una carpeta
bin
en el directorio de la función. Haga referencia a ellos con el nombre de archivo, como#r "MyAssembly.dll"
.
Para más información sobre cómo cargar archivos en su carpeta de función, consulte la sección sobre administración de paquetes.
Directorios inspeccionados
El directorio que contiene el archivo de script de función se inspecciona automáticamente para buscar cambios en los ensamblados. Para inspeccionar los cambios de los ensamblado en otros directorios, agréguelos a la lista watchDirectories
en host.json.
Uso de paquetes NuGet
La forma en que los paquetes de extensión de enlace y otros paquetes de NuGet se agregan a la aplicación de funciones depende de la versión de destino del entorno de ejecución de Functions.
De forma predeterminada, el conjunto admitido de paquetes de extensión de Functions NuGet está disponible para la aplicación de funciones de script de C# mediante agrupaciones de extensiones. Para obtener más información, consulte Conjuntos de extensiones.
Si por alguna razón no puede usar agrupaciones de extensiones en el proyecto, también puede usar Azure Functions Core Tools para instalar extensiones basadas en enlaces definidos en los archivos function.json de la aplicación. Al usar Core Tools para registrar extensiones, asegúrese de usar la opción --csx
. Para obtener más información, vea instalación de extensiones func.
De forma predeterminada, Core Tools lee los archivos function.json y agrega los paquetes necesarios a un archivo de proyecto de biblioteca de clases de C# extensions.csproj en la raíz del sistema de archivos de la aplicación de funciones (wwwroot). Dado que Core Tools usa dotnet.exe, puede usarlo para agregar cualquier referencia de paquete NuGet a este archivo de extensiones. Durante la instalación, Core Tools compila extensions.csproj para instalar las bibliotecas necesarias. Este es un ejemplo del archivo extensions.csproj en el que se agrega una referencia a la versión 1.1.0 de Microsoft.ProjectOxford.Face:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.ProjectOxford.Face" Version="1.1.0" />
</ItemGroup>
</Project>
Nota
Para el script de C# (.csx), debe establecer TargetFramework
en el valor netstandard2.0
. No se admiten otras plataformas de destino, como net6.0
.
Para usar una fuente NuGet personalizada, especifique la fuente en un archivo Nuget.Config en la carpeta raíz de la aplicación de funciones. Para más información, vea Configuring NuGet behavior (Configuración del comportamiento de NuGet).
Si solo está trabajando en el proyecto en el portal, deberá crear manualmente el archivo extensions.csproj o un archivo Nuget.Config directamente en el sitio. Para obtener más información, consulte Instalación manual de extensiones.
Variables de entorno
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:
public static void Run(TimerInfo myTimer, ILogger log)
{
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
log.LogInformation(GetEnvironmentVariable("AzureWebJobsStorage"));
log.LogInformation(GetEnvironmentVariable("WEBSITE_SITE_NAME"));
}
public static string GetEnvironmentVariable(string name)
{
return name + ": " +
System.Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
}
Directivas de reintentos
Functions admite dos directivas de reintento integradas. Para más información, consulte Directivas de reintentos.
Esta es la directiva de reintentos del archivo function.json:
{
"disabled": false,
"bindings": [
{
....
}
],
"retry": {
"strategy": "fixedDelay",
"maxRetryCount": 4,
"delayInterval": "00:00:10"
}
}
Propiedad de function.json | Descripción |
---|---|
strategy | Use fixedDelay . |
maxRetryCount | Necesario. Número máximo de reintentos permitidos por ejecución de función. -1 significa que se reintentará indefinidamente. |
delayInterval | Retraso que se usa entre reintentos. Especifíquelo como una cadena con el formato HH:mm:ss . |
Enlace en tiempo de ejecución
En C# y otros lenguajes .NET, puede usar un patrón de enlace imperativo, en contraposición a los enlaces declarativos de function.json. 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. Con este patrón, se pueden establecer enlaces compatibles de entrada y salida sobre la marcha en el código de función.
Defina un enlace imperativo como se indica a continuación:
- No incluya una entrada en function.json para los enlaces imperativos deseados.
- Pase un parámetro de entrada
Binder binder
oIBinder binder
. - Utilice el siguiente patrón de C# para realizar el enlace de datos.
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. T
no puede ser un tipo de parámetro out
(como out JObject
). Por ejemplo, el enlace de salida de la tabla de Mobile Apps admite seis tipos de salida, pero solo se puede usar ICollector<T> o IAsyncCollector<T>
para T
.
Ejemplo de un único atributo
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.
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host.Bindings.Runtime;
public static async Task Run(string input, Binder binder)
{
using (var writer = await binder.BindAsync<TextWriter>(new BlobAttribute("samples-output/path")))
{
writer.Write("Hello World!!");
}
}
BlobAttribute define el enlace de entrada o salida del blob de almacenamiento, y TextWriter es un tipo de enlace de salida admitido.
Ejemplo de varios atributos
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
). 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>()
. Use un parámetro Binder
, no IBinder
. Por ejemplo:
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host.Bindings.Runtime;
public static async Task Run(string input, Binder binder)
{
var attributes = new Attribute[]
{
new BlobAttribute("samples-output/path"),
new StorageAccountAttribute("MyStorageAccount")
};
using (var writer = await binder.BindAsync<TextWriter>(attributes))
{
writer.Write("Hello World!");
}
}
En la tabla siguiente, aparecen los atributos de .NET para cada tipo de enlace, así como los paquetes en los que se definen.
Conversión de una aplicación de script de C# en un proyecto de C#
La forma más sencilla de convertir una aplicación de función de script de C# en un proyecto compilado de biblioteca de clases de C# es comenzar con un nuevo proyecto. A continuación, para cada función, puede migrar el código y la configuración de cada archivo run.csx y function.json de una carpeta de funciones a un único archivo de código de biblioteca de clases .cs nuevo. Por ejemplo, cuando tenga una función de script C# con nombre HelloWorld
tendrá dos archivos: HelloWorld/run.csx
y HelloWorld/function.json
. Para esta función, se crea un archivo de código llamado HelloWorld.cs
en su nuevo proyecto de biblioteca de clases.
Si utiliza secuencias de comandos C# para editar el portal, puede descargar el contenido de la aplicación en su equipo local. Elija la opción Contenido del sitio en lugar de CContenido y proyecto de Visual Studio. No es necesario generar un proyecto ni incluir la configuración de la aplicación en la descarga. Está definiendo un nuevo entorno de desarrollo, y este entorno no debería tener los mismos permisos que el entorno de su aplicación alojada.
Estas instrucciones muestran cómo convertir funciones de script de C# (que se ejecutan en proceso con el host de funciones) en funciones de biblioteca de clases de C# que se ejecutan en un proceso trabajador aislado.
Complete la sección Crear un proyecto de aplicación de funciones desde su inicio rápido preferido:
Si su código de script C# original incluye un archivo
extensions.csproj
o varios archivosfunction.proj
, copie las referencias a paquetes de estos archivos y agréguelas al archivo.csproj
en el mismoItemGroup
del nuevo proyecto junto con las dependencias del núcleo de funciones.Sugerencia
La conversión ofrece una buena oportunidad para actualizar a las últimas versiones de sus dependencias. Si lo hace, podría requerir cambios de código adicionales en un paso posterior.
Copie el contenido del archivo
host.json
original en el archivohost.json
del nuevo proyecto, excepto la secciónextensionBundles
(los proyectos C# compilados no utilizan paquetes de extensiones y debe agregar explícitamente referencias a todas las extensiones utilizadas por sus funciones). Al fusionar archivos host.json, recuerde que el esquemahost.json
está versionado, y que la mayoría de las aplicaciones utilizan la versión 2.0. El contenido de la secciónextensions
puede variar en función de las versiones específicas de las extensiones de enlace utilizadas por sus funciones. Consulte los artículos de referencia de las extensiones individuales para aprender a configurar correctamente el host.json para sus versiones específicas.Para cualquier archivo compartido referenciado por una
#load
directiva, cree un nuevo archivo.cs
para cada una de estas referencias compartidas. Lo más sencillo es crear un nuevo archivo.cs
para cada definición de clase compartida. Si hay métodos estáticos sin clase, es necesario definir nuevas clases para estos métodos.Realice las siguientes tareas para cada carpeta
<FUNCTION_NAME>
de su proyecto original:Cree un nuevo archivo denominado
<FUNCTION_NAME>.cs
, reemplazando<FUNCTION_NAME>
por el nombre de la carpeta que definió la función de script de C#. Puede crear un nuevo archivo de código de función a partir de una de las plantillas específicas de activación de la siguiente manera:Utilizando el comando
func new --name <FUNCTION_NAME>
y eligiendo la plantilla de activación correcta en el indicador.Copie las instrucciones
using
del archivorun.csx
y agréguelas al nuevo archivo. No necesita directivas#r
.Para cualquier instrucción
#load
del archivorun.csx
, agregue una nueva instrucciónusing
para el espacio de nombres que usó para el código compartido.En el nuevo archivo, defina una clase para la función en el espacio de nombres que usa para el proyecto.
Cree un nuevo método llamado
RunHandler
o algo similar. Este nuevo método sirve como nuevo punto de entrada de la función.Copie el método estático que representa la función, junto con las funciones a las que llama, desde
run.csx
a la nueva clase como segundo método. Desde el nuevo método que creó en el paso anterior, llame a este método estático. Este paso de direccionamiento indirecto resulta útil para navegar por las diferencias a medida que continúa la actualización. Puede mantener el método original exactamente igual y, simplemente, controlar sus entradas desde el nuevo contexto. Es posible que tenga que crear parámetros en el nuevo método que, a continuación, pasará a la llamada de método estático. Después de confirmar que la migración funcionó según lo previsto, puede quitar este nivel adicional de direccionamiento indirecto.Para cada enlace del archivo
function.json
, agregue el atributo correspondiente al nuevo método. Para encontrar rápidamente ejemplos de fijaciones, consulte Agregar fijaciones manualmente basándose en ejemplos.Si aún no lo ha hecho, agregue al proyecto los paquetes de extensión que requieran los enlaces.
Vuelva a crear cualquier configuración de la aplicación requerida por su aplicación en la colección
Values
del archivo local.settings.json.Compruebe que su proyecto se ejecuta de forma local:
Utilice
func start
para ejecutar la aplicación desde la línea de comandos. Para obtener más información, consulte Ejecutar funciones de forma local.Publique su proyecto en una nueva aplicación de función en Azure:
Cree sus recursos Azure e implemente el proyecto de código en Azure utilizando el comando
func azure functionapp publish <APP_NAME>
. Para obtener más información, consulte Implementación de los archivos de proyecto.
Conversión de función de ejemplo
En esta sección, se muestra un ejemplo de la migración de una sola función.
La función original en el scripting de C# tiene dos archivos:
HelloWorld/function.json
HelloWorld/run.csx
El contenido de HelloWorld/function.json
es:
{
"bindings": [
{
"authLevel": "FUNCTION",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
}
]
}
El contenido de HelloWorld/run.csx
es:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
string responseMessage = string.IsNullOrEmpty(name)
? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
: $"Hello, {name}. This HTTP triggered function executed successfully.";
return new OkObjectResult(responseMessage);
}
Después de migrar al modelo de trabajo aislado con la integración de ASP.NET Core, estos se reemplazan por un único HelloWorld.cs
:
using System.Net;
using Microsoft.Azure.Functions.Worker;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
namespace MyFunctionApp
{
public class HelloWorld
{
private readonly ILogger _logger;
public HelloWorld(ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<HelloWorld>();
}
[Function("HelloWorld")]
public async Task<IActionResult> RunHandler([HttpTrigger(AuthorizationLevel.Function, "get")] HttpRequest req)
{
return await Run(req, _logger);
}
// From run.csx
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
string responseMessage = string.IsNullOrEmpty(name)
? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
: $"Hello, {name}. This HTTP triggered function executed successfully.";
return new OkObjectResult(responseMessage);
}
}
}
Configuración y ejemplos de enlace
Esta sección contiene referencias y ejemplos para definir desencadenadores y enlaces en un script C#.
Desencadenador de blobs
En la siguiente tabla se explican las propiedades de configuración de enlace para el script de C# que se establecen en el archivo function.json.
Propiedad de function.json | Descripción |
---|---|
type | Se debe establecer en blobTrigger . Esta propiedad se establece automáticamente cuando se crea el desencadenador en Azure Portal. |
direction | Se debe establecer en in . Esta propiedad se establece automáticamente cuando se crea el desencadenador en Azure Portal. |
name | Nombre de la variable que representa el blob en el código de la función. |
path | El contenedor que se va a supervisar. Puede ser un patrón de nombre de blob. |
connection | Nombre de una configuración de aplicación o de una colección de configuraciones de aplicación que especifica cómo conectarse a los blobs de Azure. Consulte Conexiones. |
El siguiente ejemplo muestra una definición de activador de blob en un archivo function.json y el código que utiliza el enlace. La función escribe un registro cuando se agrega o actualiza un blob en el contenedor samples-workitems
.
Estos son los datos de enlace del archivo function.json:
{
"disabled": false,
"bindings": [
{
"name": "myBlob",
"type": "blobTrigger",
"direction": "in",
"path": "samples-workitems/{name}",
"connection":"MyStorageAccountAppSetting"
}
]
}
La cadena {name}
en la ruta de acceso del desencadenador de blobs samples-workitems/{name}
crea una {name}
que puede usar en el código de función para acceder al nombre de archivo del blob de desencadenamiento. Para obtener más información, consulte Patrones de nombre de blob.
Este es el código de script de C# que se enlaza a Stream
:
public static void Run(Stream myBlob, string name, ILogger log)
{
log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes");
}
Este es el código de script de C# que se enlaza a CloudBlockBlob
:
#r "Microsoft.WindowsAzure.Storage"
using Microsoft.WindowsAzure.Storage.Blob;
public static void Run(CloudBlockBlob myBlob, string name, ILogger log)
{
log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name}\nURI:{myBlob.StorageUri}");
}
Entrada de blob
En la siguiente tabla se explican las propiedades de configuración de enlace para el script de C# que se establecen en el archivo function.json.
Propiedad de function.json | Descripción |
---|---|
type | Se debe establecer en blob . |
direction | Se debe establecer en in . |
name | Nombre de la variable que representa el blob en el código de la función. |
path | Ruta de acceso al blob. |
connection | Nombre de una configuración de aplicación o de una colección de configuraciones de aplicación que especifica cómo conectarse a los blobs de Azure. Consulte Conexiones. |
En el ejemplo siguiente se muestran enlaces de entrada y salida de blobs en un archivo function.json y código de script de C# que usa los enlaces. La función realiza una copia de un blob de texto. La función se activa mediante un mensaje de cola que contiene el nombre del blob que se va a copiar. El nuevo blob se denomina {nombreoriginaldelblob}-Copy.
En el archivo function.json, la propiedad de metadatos queueTrigger
se utiliza para especificar el nombre del blob en las propiedades de path
:
{
"bindings": [
{
"queueName": "myqueue-items",
"connection": "MyStorageConnectionAppSetting",
"name": "myQueueItem",
"type": "queueTrigger",
"direction": "in"
},
{
"name": "myInputBlob",
"type": "blob",
"path": "samples-workitems/{queueTrigger}",
"connection": "MyStorageConnectionAppSetting",
"direction": "in"
},
{
"name": "myOutputBlob",
"type": "blob",
"path": "samples-workitems/{queueTrigger}-Copy",
"connection": "MyStorageConnectionAppSetting",
"direction": "out"
}
],
"disabled": false
}
Este es el código de script de C#:
public static void Run(string myQueueItem, string myInputBlob, out string myOutputBlob, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
myOutputBlob = myInputBlob;
}
Salida del blob
En la siguiente tabla se explican las propiedades de configuración de enlace para el script de C# que se establecen en el archivo function.json.
Propiedad de function.json | Descripción |
---|---|
type | Se debe establecer en blob . |
direction | Se debe establecer en out . |
name | Nombre de la variable que representa el blob en el código de la función. |
path | Ruta de acceso al blob. |
connection | Nombre de una configuración de aplicación o de una colección de configuraciones de aplicación que especifica cómo conectarse a los blobs de Azure. Consulte Conexiones. |
En el ejemplo siguiente se muestran enlaces de entrada y salida de blobs en un archivo function.json y código de script de C# que usa los enlaces. La función realiza una copia de un blob de texto. La función se activa mediante un mensaje de cola que contiene el nombre del blob que se va a copiar. El nuevo blob se denomina {nombreoriginaldelblob}-Copy.
En el archivo function.json, la propiedad de metadatos queueTrigger
se utiliza para especificar el nombre del blob en las propiedades de path
:
{
"bindings": [
{
"queueName": "myqueue-items",
"connection": "MyStorageConnectionAppSetting",
"name": "myQueueItem",
"type": "queueTrigger",
"direction": "in"
},
{
"name": "myInputBlob",
"type": "blob",
"path": "samples-workitems/{queueTrigger}",
"connection": "MyStorageConnectionAppSetting",
"direction": "in"
},
{
"name": "myOutputBlob",
"type": "blob",
"path": "samples-workitems/{queueTrigger}-Copy",
"connection": "MyStorageConnectionAppSetting",
"direction": "out"
}
],
"disabled": false
}
Este es el código de script de C#:
public static void Run(string myQueueItem, string myInputBlob, out string myOutputBlob, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
myOutputBlob = myInputBlob;
}
Desencadenador de RabbitMQ
En el ejemplo siguiente se muestra un enlace de desencadenador de RabbitMQ en un archivo function.json y una función de script de C# que usa el enlace. La función Lee y registra el mensaje de RabbitMQ.
Estos son los datos de enlace del archivo function.json:
{
"bindings": [
{
"name": "myQueueItem",
"type": "rabbitMQTrigger",
"direction": "in",
"queueName": "queue",
"connectionStringSetting": "rabbitMQConnectionAppSetting"
}
]
}
Este es el código de script de C#:
using System;
public static void Run(string myQueueItem, ILogger log)
{
log.LogInformation($"C# Script RabbitMQ trigger function processed: {myQueueItem}");
}
Desencadenador de cola
En la siguiente tabla se explican las propiedades de configuración de enlace para el script de C# que se establecen en el archivo function.json.
Propiedad de function.json | Descripción |
---|---|
type | Se debe establecer en queueTrigger . Esta propiedad se establece automáticamente cuando se crea el desencadenador en Azure Portal. |
direction | Solo en el archivo function.json. Se debe establecer en in . Esta propiedad se establece automáticamente cuando se crea el desencadenador en Azure Portal. |
name | El nombre de la variable que contiene la carga del elemento de cola en el código de función. |
queueName | Nombre de la cola que se sondea. |
connection | Nombre de una configuración de aplicación o colección de configuraciones que especifica cómo conectarse a las colas de Azure. Consulte Conexiones. |
En el ejemplo siguiente se muestra un enlace de desencadenador de cola de un archivo function.json y código de script de C# que usa el enlace. La función sondea la cola myqueue-items
y escribe un registro cada vez que se procesa un elemento de cola.
Este es el archivo function.json:
{
"disabled": false,
"bindings": [
{
"type": "queueTrigger",
"direction": "in",
"name": "myQueueItem",
"queueName": "myqueue-items",
"connection":"MyStorageConnectionAppSetting"
}
]
}
Este es el código de script de C#:
#r "Microsoft.WindowsAzure.Storage"
using Microsoft.Extensions.Logging;
using Microsoft.WindowsAzure.Storage.Queue;
using System;
public static void Run(CloudQueueMessage myQueueItem,
DateTimeOffset expirationTime,
DateTimeOffset insertionTime,
DateTimeOffset nextVisibleTime,
string queueTrigger,
string id,
string popReceipt,
int dequeueCount,
ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem.AsString}\n" +
$"queueTrigger={queueTrigger}\n" +
$"expirationTime={expirationTime}\n" +
$"insertionTime={insertionTime}\n" +
$"nextVisibleTime={nextVisibleTime}\n" +
$"id={id}\n" +
$"popReceipt={popReceipt}\n" +
$"dequeueCount={dequeueCount}");
}
Salida de cola
En la siguiente tabla se explican las propiedades de configuración de enlace para el script de C# que se establecen en el archivo function.json.
Propiedad de function.json | Descripción |
---|---|
type | Se debe establecer en queue . Esta propiedad se establece automáticamente cuando se crea el desencadenador en Azure Portal. |
direction | Se debe establecer en out . Esta propiedad se establece automáticamente cuando se crea el desencadenador en Azure Portal. |
name | Nombre de la variable que representa la cola en el código de la función. Se establece en $return para hacer referencia al valor devuelto de la función. |
queueName | Nombre de la cola. |
connection | Nombre de una configuración de aplicación o colección de configuraciones que especifica cómo conectarse a las colas de Azure. Consulte Conexiones. |
En el ejemplo siguiente se muestra un enlace de desencadenador HTTP de un archivo function.json y el código de script de C# que usa el enlace. La función crea un elemento de cola con una carga del objeto CustomQueueMessage para cada una de las solicitudes HTTP recibidas.
Este es el archivo function.json:
{
"bindings": [
{
"type": "httpTrigger",
"direction": "in",
"authLevel": "function",
"name": "input"
},
{
"type": "http",
"direction": "out",
"name": "$return"
},
{
"type": "queue",
"direction": "out",
"name": "$return",
"queueName": "outqueue",
"connection": "MyStorageConnectionAppSetting"
}
]
}
Este es el código de script de C# que crea un único mensaje de cola:
public class CustomQueueMessage
{
public string PersonName { get; set; }
public string Title { get; set; }
}
public static CustomQueueMessage Run(CustomQueueMessage input, ILogger log)
{
return input;
}
Puede enviar varios mensajes a la vez mediante el uso de un parámetro ICollector
o IAsyncCollector
. Este es el código de script de C# que envía varios mensajes, uno con los datos de la solicitud HTTP y otro con valores codificados de forma rígida:
public static void Run(
CustomQueueMessage input,
ICollector<CustomQueueMessage> myQueueItems,
ILogger log)
{
myQueueItems.Add(input);
myQueueItems.Add(new CustomQueueMessage { PersonName = "You", Title = "None" });
}
Entrada de tabla
En esta sección se describe la compatibilidad solo con la versión de Tables API de la extensión.
En la siguiente tabla se explican las propiedades de configuración de enlace para el script de C# que se establecen en el archivo function.json.
Propiedad de function.json | Descripción |
---|---|
type | Se debe establecer en table . Esta propiedad se establece automáticamente cuando se crea el enlace en Azure Portal. |
direction | Se debe establecer en in . Esta propiedad se establece automáticamente cuando se crea el enlace en Azure Portal. |
name | Nombre de la variable que representa la tabla o la entidad en el código de la función. |
tableName | Nombre de la tabla. |
partitionKey | Opcional. Clave de partición de la entidad de tabla que se va a leer. |
rowKey | Opcional. Clave de fila de la entidad de tabla que se va a leer. No se puede usar con las propiedades take ni filter . |
take | Opcional. Número máximo de entidades que se devolverán. No se puede usar con rowKey . |
filter | Opcional. Expresión de filtro de OData para las entidades que se devolverá de la tabla. No se puede usar con rowKey . |
connection | Nombre de una configuración de aplicación o colección de parámetros que especifica cómo conectarse al servicio de tablas. Consulte Conexiones. |
En el ejemplo siguiente se muestra un enlace de entrada de la tabla en un archivo function.json y código de script de C# que usa el enlace. La función usa un desencadenador de cola para leer una fila de tabla única.
El archivo function.json especifica un valor partitionKey
y un valor rowKey
. El valor {queueTrigger}
de rowKey
indica que la clave de fila procede de la cadena del mensaje en la cola.
{
"bindings": [
{
"queueName": "myqueue-items",
"connection": "MyStorageConnectionAppSetting",
"name": "myQueueItem",
"type": "queueTrigger",
"direction": "in"
},
{
"name": "personEntity",
"type": "table",
"tableName": "Person",
"partitionKey": "Test",
"rowKey": "{queueTrigger}",
"connection": "MyStorageConnectionAppSetting",
"direction": "in"
}
],
"disabled": false
}
Este es el código de script de C#:
#r "Azure.Data.Tables"
using Microsoft.Extensions.Logging;
using Azure.Data.Tables;
public static void Run(string myQueueItem, Person personEntity, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
log.LogInformation($"Name in Person entity: {personEntity.Name}");
}
public class Person : ITableEntity
{
public string Name { get; set; }
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public DateTimeOffset? Timestamp { get; set; }
public ETag ETag { get; set; }
}
Salida de tabla
En esta sección se describe la compatibilidad solo con la versión de Tables API de la extensión.
En la siguiente tabla se explican las propiedades de configuración de enlace para el script de C# que se establecen en el archivo function.json.
Propiedad de function.json | Descripción |
---|---|
type | Se debe establecer en table . Esta propiedad se establece automáticamente cuando se crea el enlace en Azure Portal. |
direction | Se debe establecer en out . Esta propiedad se establece automáticamente cuando se crea el enlace en Azure Portal. |
name | Nombre de la variable que se usa en el código de la función que representa la tabla o entidad. Se establece en $return para hacer referencia al valor devuelto de la función. |
tableName | Nombre de la tabla en la que se va a escribir. |
partitionKey | Clave de partición de la entidad de tabla que se va a escribir. |
rowKey | Clave de fila de la entidad de tabla que se va a escribir. |
connection | Nombre de una configuración de aplicación o colección de parámetros que especifica cómo conectarse al servicio de tablas. Consulte Conexiones. |
En el ejemplo siguiente se muestra un enlace de salida de la tabla en un archivo function.json y código de script de C# que usa el enlace. La función escribe varias entidades de tabla.
Este es el archivo function.json:
{
"bindings": [
{
"name": "input",
"type": "manualTrigger",
"direction": "in"
},
{
"tableName": "Person",
"connection": "MyStorageConnectionAppSetting",
"name": "tableBinding",
"type": "table",
"direction": "out"
}
],
"disabled": false
}
Este es el código de script de C#:
public static void Run(string input, ICollector<Person> tableBinding, ILogger log)
{
for (int i = 1; i < 10; i++)
{
log.LogInformation($"Adding Person entity {i}");
tableBinding.Add(
new Person() {
PartitionKey = "Test",
RowKey = i.ToString(),
Name = "Name" + i.ToString() }
);
}
}
public class Person
{
public string PartitionKey { get; set; }
public string RowKey { get; set; }
public string Name { get; set; }
}
Desencadenador de temporizador
En la siguiente tabla se explican las propiedades de configuración de enlace para el script de C# que se establecen en el archivo function.json.
Propiedad de function.json | Descripción |
---|---|
type | Se debe establecer en timerTrigger . Esta propiedad se establece automáticamente cuando se crea el desencadenador en Azure Portal. |
direction | Se debe establecer en in . Esta propiedad se establece automáticamente cuando se crea el desencadenador en Azure Portal. |
name | Nombre de la variable que representa el objeto de temporizador en el código de la función. |
schedule | Una expresión CRON o un valor TimeSpan. TimeSpan solamente se puede usar para una aplicación de función que se ejecuta en un plan de App Service. Puede colocar la expresión de programación en una configuración de aplicación y establecer esta propiedad en el nombre de dicha configuración encapsulado en signos % , como en este ejemplo: "%ScheduleAppSetting%". |
runOnStartup | Si true , la función se invoca cuando se inicia el entorno de ejecución. Por ejemplo, el entorno de ejecución se inicia cuando la aplicación de función se reactiva después de estar inactiva por inactividad, cuando la aplicación de función se reinicia debido a cambios de función y cuando la aplicación de función se escala horizontalmente. Utilícelo con precaución. runOnStartup rara vez o nunca debe establecerse en true , especialmente en producción. |
useMonitor | Establezca esta propiedad en true o false para indicar si la programación se debe supervisar. La supervisión de la programación conserva las apariciones de programación para ayudar a garantizar que la programación se mantiene correctamente aunque las instancias de aplicación de función se reinicien. Si no se establece explícitamente, el valor predeterminado es true para las programaciones que tienen un intervalo de periodicidad superior o igual a 1 minuto. Para las programaciones que se desencadenan más de una vez por minuto, el valor predeterminado es false . |
En el ejemplo siguiente se muestra un enlace de desencadenador de temporizador en un archivo function.json y una función de script de C# que usa el enlace. La función escribe un registro que indica si esta invocación de función se debe a una repetición de la programación no ejecutada. El objeto TimerInfo
se pasa a la función.
Estos son los datos de enlace del archivo function.json:
{
"schedule": "0 */5 * * * *",
"name": "myTimer",
"type": "timerTrigger",
"direction": "in"
}
Este es el código de script de C#:
public static void Run(TimerInfo myTimer, ILogger log)
{
if (myTimer.IsPastDue)
{
log.LogInformation("Timer is running late!");
}
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}" );
}
Desencadenador HTTP
En la siguiente tabla se explican las propiedades de configuración de desencadenador que se establecen en el archivo function.json:
Propiedad de function.json | Descripción |
---|---|
type | Requerida: se debe establecer en httpTrigger . |
direction | Requerida: se debe establecer en in . |
name | Requerida: nombre de variable que se usa en el código de la función para la solicitud o el cuerpo de la solicitud. |
authLevel | Determina qué claves, si las hubiera, deben estar presentes en la solicitud para poder invocar a la función. Para ver los valores admitidos, consulte Nivel de autorización. |
methods | Una matriz de los métodos HTTP a los que responde la función. Si no se especifica, la función responde a todos los métodos HTTP. Consulte cómo personalizar el punto de conexión HTTP. |
route | Define la plantilla de ruta y controla las direcciones URL de solicitud a las que responde la función. El valor predeterminado es <functionname> si no se proporciona ninguno. Para más información, consulte cómo personalizar el punto de conexión HTTP. |
webHookType | Compatible solo con la versión 1.x del runtime. Configura el desencadenador HTTP para que actúe como un receptor de webhook para el proveedor especificado. Para ver los valores admitidos, consulte Tipo de webhook. |
En el ejemplo siguiente se muestra un enlace de desencadenador en un archivo function.json y una función de script de C# que usa el enlace. La función busca un parámetro name
en la cadena de consulta o en el cuerpo de la solicitud HTTP.
Este es el archivo function.json:
{
"disabled": false,
"bindings": [
{
"authLevel": "function",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
}
]
}
Este es el código de script de C# que se enlaza a HttpRequest
:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
public static async Task<IActionResult> Run(HttpRequest req, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string name = req.Query["name"];
string requestBody = String.Empty;
using (StreamReader streamReader = new StreamReader(req.Body))
{
requestBody = await streamReader.ReadToEndAsync();
}
dynamic data = JsonConvert.DeserializeObject(requestBody);
name = name ?? data?.name;
return name != null
? (ActionResult)new OkObjectResult($"Hello, {name}")
: new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}
Puede enlazar a un objeto personalizado en lugar de HttpRequest
. Este objeto se crea a partir del cuerpo de la solicitud y se analiza como JSON. Del mismo modo, puede pasarse un tipo al enlace de la salida de respuesta HTTP y se devuelve como el cuerpo de la respuesta, con el código de estado 200
.
using System.Net;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
public static string Run(Person person, ILogger log)
{
return person.Name != null
? (ActionResult)new OkObjectResult($"Hello, {person.Name}")
: new BadRequestObjectResult("Please pass an instance of Person.");
}
public class Person {
public string Name {get; set;}
}
Salida HTTP
En la siguiente tabla se explican las propiedades de configuración de enlace que se establecen en el archivo function.json.
Propiedad | Descripción |
---|---|
type | Se debe establecer en http . |
direction | Se debe establecer en out . |
name | Nombre de la variable usado en el código de la función para la respuesta, o $return para usar el valor devuelto. |
Desencadenador de Event Hubs
En la siguiente tabla se explican las propiedades de configuración de desencadenador que se establecen en el archivo function.json:
Propiedad de function.json | Descripción |
---|---|
type | Se debe establecer en eventHubTrigger . Esta propiedad se establece automáticamente cuando se crea el desencadenador en Azure Portal. |
direction | Se debe establecer en in . Esta propiedad se establece automáticamente cuando se crea el desencadenador en Azure Portal. |
name | Nombre de la variable que representa el elemento de evento en el código de la función. |
eventHubName | Functions 2.x y versiones posteriores. El nombre del centro de eventos. Cuando el nombre del centro de eventos también está presente en la cadena de conexión, ese valor reemplaza esta propiedad en tiempo de ejecución. Puede consultarse en la configuración de la aplicación %eventHubName% . En la versión 1.x, esta propiedad se denomina path . |
consumerGroup | Una propiedad opcional que establece el grupo de consumidores que se usará para suscribirse a los eventos del centro. Si se pasa por alto, se utilizará el grupo de consumidores $Default . |
connection | Nombre de una configuración de aplicación o de una colección de configuraciones de aplicación que especifica cómo conectarse a Event Hubs. Consulte Conexiones. |
En el ejemplo siguiente se muestra un enlace de desencadenador de Event Hubs en un archivo function.json y una función de script de C# que usa el enlace. La función registra el cuerpo del mensaje del desencadenador de Event Hubs.
En los ejemplos siguientes se muestran datos de enlace de Event Hubs en el archivo function.json para la versión 2.x y las versiones posteriores del entorno de ejecución Functions.
{
"type": "eventHubTrigger",
"name": "myEventHubMessage",
"direction": "in",
"eventHubName": "MyEventHub",
"connection": "myEventHubReadConnectionAppSetting"
}
Este es el código de script de C#:
using System;
public static void Run(string myEventHubMessage, TraceWriter log)
{
log.Info($"C# function triggered to process a message: {myEventHubMessage}");
}
Para acceder a los metadatos del evento en el código de función, cree un enlace a un objeto EventData. También puede acceder a las mismas propiedades mediante el uso de expresiones de enlace en la firma del método. El ejemplo siguiente se muestran las dos maneras de obtener los mismos datos:
#r "Microsoft.Azure.EventHubs"
using System.Text;
using System;
using Microsoft.ServiceBus.Messaging;
using Microsoft.Azure.EventHubs;
public void Run(EventData myEventHubMessage,
DateTime enqueuedTimeUtc,
Int64 sequenceNumber,
string offset,
TraceWriter log)
{
log.Info($"Event: {Encoding.UTF8.GetString(myEventHubMessage.Body)}");
log.Info($"EnqueuedTimeUtc={myEventHubMessage.SystemProperties.EnqueuedTimeUtc}");
log.Info($"SequenceNumber={myEventHubMessage.SystemProperties.SequenceNumber}");
log.Info($"Offset={myEventHubMessage.SystemProperties.Offset}");
// Metadata accessed by using binding expressions
log.Info($"EnqueuedTimeUtc={enqueuedTimeUtc}");
log.Info($"SequenceNumber={sequenceNumber}");
log.Info($"Offset={offset}");
}
Para recibir eventos en un lote, convierta string
o EventData
en una matriz:
public static void Run(string[] eventHubMessages, TraceWriter log)
{
foreach (var message in eventHubMessages)
{
log.Info($"C# function triggered to process a message: {message}");
}
}
Salida de Event Hubs
En la siguiente tabla se explican las propiedades de configuración de enlace que se establecen en el archivo function.json.
Propiedad de function.json | Descripción |
---|---|
type | Se debe establecer en eventHub . |
direction | Se debe establecer en out . Este parámetro se establece automáticamente cuando se crea el enlace en Azure Portal. |
name | Nombre de la variable que se usa en el código de la función que representa el evento. |
eventHubName | Functions 2.x y versiones posteriores. El nombre del centro de eventos. Cuando el nombre del centro de eventos también está presente en la cadena de conexión, ese valor reemplaza esta propiedad en tiempo de ejecución. En Functions 1.x, esta propiedad se denomina path . |
connection | Nombre de una configuración de aplicación o de una colección de configuraciones de aplicación que especifica cómo conectarse a Event Hubs. Para más información, consulte Conexiones. |
En el ejemplo siguiente se muestra un enlace de desencadenador de centro de eventos en un archivo function.json y una función de script de C# que usa el enlace. La función escribe un mensaje a un centro de eventos.
En los ejemplos siguientes se muestran datos de enlace de Event Hubs en el archivo function.json para la versión 2.x y las versiones posteriores del entorno de ejecución Functions.
{
"type": "eventHub",
"name": "outputEventHubMessage",
"eventHubName": "myeventhub",
"connection": "MyEventHubSendAppSetting",
"direction": "out"
}
Este es el código de script de C# que crea un mensaje:
using System;
using Microsoft.Extensions.Logging;
public static void Run(TimerInfo myTimer, out string outputEventHubMessage, ILogger log)
{
String msg = $"TimerTriggerCSharp1 executed at: {DateTime.Now}";
log.LogInformation(msg);
outputEventHubMessage = msg;
}
Este es el código de script de C# que crea varios mensajes:
public static void Run(TimerInfo myTimer, ICollector<string> outputEventHubMessage, ILogger log)
{
string message = $"Message created at: {DateTime.Now}";
log.LogInformation(message);
outputEventHubMessage.Add("1 " + message);
outputEventHubMessage.Add("2 " + message);
}
Desencadenador de Event Grid
En la siguiente tabla se explican las propiedades de configuración de enlace para el script de C# que se establecen en el archivo function.json. No hay parámetros de constructor ni propiedades que establecer en el atributo EventGridTrigger
.
Propiedad de function.json | Descripción |
---|---|
type | Requerida: se debe establecer en eventGridTrigger . |
direction | Requerida: se debe establecer en in . |
name | Requerido: el nombre de la variable que se utiliza en el código de función para el parámetro que recibe los datos del evento. |
En el ejemplo siguiente se muestra un desencadenador de Event Grid definido en el archivo function.json.
Estos son los datos de enlace del archivo function.json:
{
"bindings": [
{
"type": "eventGridTrigger",
"name": "eventGridEvent",
"direction": "in"
}
],
"disabled": false
}
Este es un ejemplo de una función de script de C# que utiliza un parámetro de enlace EventGridEvent
:
#r "Azure.Messaging.EventGrid"
using Azure.Messaging.EventGrid;
using Microsoft.Extensions.Logging;
public static void Run(EventGridEvent eventGridEvent, ILogger log)
{
log.LogInformation(eventGridEvent.Data.ToString());
}
Este es un ejemplo de una función de script de C# que utiliza un parámetro de enlace JObject
:
#r "Newtonsoft.Json"
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public static void Run(JObject eventGridEvent, TraceWriter log)
{
log.Info(eventGridEvent.ToString(Formatting.Indented));
}
Enlace de salida de Event Grid
En la siguiente tabla se explican las propiedades de configuración de enlace para el script de C# que se establecen en el archivo function.json.
Propiedad de function.json | Descripción |
---|---|
type | Se debe establecer en eventGrid . |
direction | Se debe establecer en out . Este parámetro se establece automáticamente cuando se crea el enlace en Azure Portal. |
name | Nombre de la variable que se usa en el código de la función que representa el evento. |
topicEndpointUri | Nombre de un valor de aplicación que contiene el URI para el tema personalizado, como MyTopicEndpointUri . |
topicKeySetting | Nombre de un valor de aplicación que contiene una clave de acceso para el tema personalizado. |
En el ejemplo siguiente se muestran los datos del enlace de salida de Event Grid en el archivo function.json.
{
"type": "eventGrid",
"name": "outputEvent",
"topicEndpointUri": "MyEventGridTopicUriSetting",
"topicKeySetting": "MyEventGridTopicKeySetting",
"direction": "out"
}
Este es el código de script de C# que crea un evento:
#r "Microsoft.Azure.EventGrid"
using System;
using Microsoft.Azure.EventGrid.Models;
using Microsoft.Extensions.Logging;
public static void Run(TimerInfo myTimer, out EventGridEvent outputEvent, ILogger log)
{
outputEvent = new EventGridEvent("message-id", "subject-name", "event-data", "event-type", DateTime.UtcNow, "1.0");
}
Este es el código de script de C# que crea varios eventos:
#r "Microsoft.Azure.EventGrid"
using System;
using Microsoft.Azure.EventGrid.Models;
using Microsoft.Extensions.Logging;
public static void Run(TimerInfo myTimer, ICollector<EventGridEvent> outputEvent, ILogger log)
{
outputEvent.Add(new EventGridEvent("message-id-1", "subject-name", "event-data", "event-type", DateTime.UtcNow, "1.0"));
outputEvent.Add(new EventGridEvent("message-id-2", "subject-name", "event-data", "event-type", DateTime.UtcNow, "1.0"));
}
Desencadenador de Service Bus
En la siguiente tabla se explican las propiedades de configuración de enlace que se establecen en el archivo function.json.
Propiedad de function.json | Descripción |
---|---|
type | Se debe establecer en serviceBusTrigger . Esta propiedad se establece automáticamente cuando se crea el desencadenador en Azure Portal. |
direction | Se debe establecer en in . Esta propiedad se establece automáticamente cuando se crea el desencadenador en Azure Portal. |
name | Nombre de la variable que representa el mensaje de cola o tema en el código de la función. |
queueName | Nombre de la cola que se debe supervisar. Se establece únicamente si se supervisa una cola, no un tema. |
topicName | Nombre del tema que se debe supervisar. Se establece únicamente si se supervisa un tema, no una cola. |
subscriptionName | Nombre de la suscripción que se debe supervisar. Se establece únicamente si se supervisa un tema, no una cola. |
connection | Nombre de una configuración de aplicación o colección de parámetros que especifica cómo conectarse a Service Bus. Consulte Conexiones. |
accessRights | Derechos de acceso para la cadena de conexión. Los valores disponibles son manage y listen . El valor predeterminado es manage , lo que indica que connection tiene el permiso manage . Si usa una cadena de conexión que no tiene el permiso Administrar, establezca accessRights en "listen". De lo contrario, el runtime de Functions puede intentar realizar operaciones que requieran derechos de administración y no conseguirlo. En la versión 2.x y posteriores de Azure Functions, esta propiedad no está disponible porque la versión más reciente del SDK de Service Bus no admite operaciones de administración. |
isSessionsEnabled | true si se conecta a una cola o suscripción true . En caso contrario, false , que es el valor predeterminado. |
autoComplete | true cuando el desencadenador debe llamar automáticamente a Complete después del procesamiento o si el código de la función llamará manualmente a Complete.La configuración en false solo se admite en C#.Si se establece en true , el desencadenador completa automáticamente el mensaje si la ejecución de la función se completa correctamente y abandona el mensaje en caso contrario.<br/When establecido en false , es responsable de llamar a los métodos ServiceBusReceiver para completar, abandonar o desactivar el mensaje, la sesión o el lote. Si se produce una excepción (y no se llama a ninguno de los métodos ServiceBusReceiver ), se mantiene el bloqueo. Una vez que el bloqueo expira, el mensaje se vuelve a poner en cola con la DeliveryCount incrementada y el bloqueo se renueva automáticamente.Esta propiedad solo está disponible en la versión 2 de Azure Functions o en versiones posteriores. |
En el ejemplo siguiente se muestra un enlace de desencadenador de Service Bus en un archivo function.json y una función de script de C# que usa el enlace. La función lee metadatos de mensaje y registra un mensaje de cola de Service Bus.
Estos son los datos de enlace del archivo function.json:
{
"bindings": [
{
"queueName": "testqueue",
"connection": "MyServiceBusConnection",
"name": "myQueueItem",
"type": "serviceBusTrigger",
"direction": "in"
}
],
"disabled": false
}
Este es el código de script de C#:
using System;
public static void Run(string myQueueItem,
Int32 deliveryCount,
DateTime enqueuedTimeUtc,
string messageId,
TraceWriter log)
{
log.Info($"C# ServiceBus queue trigger function processed message: {myQueueItem}");
log.Info($"EnqueuedTimeUtc={enqueuedTimeUtc}");
log.Info($"DeliveryCount={deliveryCount}");
log.Info($"MessageId={messageId}");
}
Salida de Service Bus
En la siguiente tabla se explican las propiedades de configuración de enlace que se establecen en el archivo function.json.
Propiedad de function.json | Descripción |
---|---|
type | Se debe establecer en serviceBus . Esta propiedad se establece automáticamente cuando se crea el desencadenador en Azure Portal. |
direction | Se debe establecer en out . Esta propiedad se establece automáticamente cuando se crea el desencadenador en Azure Portal. |
name | Nombre de la variable que representa el mensaje de cola o tema en el código de la función. Se establece en "$return" para hacer referencia al valor devuelto de la función. |
queueName | Nombre de la cola. Se establece únicamente si se envían mensajes de cola, no de tema. |
topicName | Nombre del tema. Se establece únicamente si se envían mensajes de tema, no de cola. |
connection | Nombre de una configuración de aplicación o colección de parámetros que especifica cómo conectarse a Service Bus. Consulte Conexiones. |
accessRights (solo v1) | Derechos de acceso para la cadena de conexión. Los valores disponibles son manage y listen . El valor predeterminado es manage , lo que indica que connection tiene el permiso manage . Si usa una cadena de conexión que no tiene el permiso Administrar, establezca accessRights en "listen". De lo contrario, el runtime de Functions puede intentar realizar operaciones que requieran derechos de administración y no conseguirlo. En la versión 2.x y posteriores de Azure Functions, esta propiedad no está disponible porque la versión más reciente del SDK de Service Bus no admite operaciones de administración. |
En el ejemplo siguiente se muestra un enlace de salida de Service Bus en un archivo function.json y una función de script de C# que usa el enlace. La función usa un desencadenador de temporizador para enviar un mensaje de cola cada 15 segundos.
Estos son los datos de enlace del archivo function.json:
{
"bindings": [
{
"schedule": "0/15 * * * * *",
"name": "myTimer",
"runsOnStartup": true,
"type": "timerTrigger",
"direction": "in"
},
{
"name": "outputSbQueue",
"type": "serviceBus",
"queueName": "testqueue",
"connection": "MyServiceBusConnection",
"direction": "out"
}
],
"disabled": false
}
Este es el código de script de C# que crea un único mensaje:
public static void Run(TimerInfo myTimer, ILogger log, out string outputSbQueue)
{
string message = $"Service Bus queue message created at: {DateTime.Now}";
log.LogInformation(message);
outputSbQueue = message;
}
Este es el código de script de C# que crea varios mensajes:
public static async Task Run(TimerInfo myTimer, ILogger log, IAsyncCollector<string> outputSbQueue)
{
string message = $"Service Bus queue messages created at: {DateTime.Now}";
log.LogInformation(message);
await outputSbQueue.AddAsync("1 " + message);
await outputSbQueue.AddAsync("2 " + message);
}
Desencadenador de Azure Cosmos DB v2
En esta sección se describe la compatibilidad solo para la versión 4.x+ de la extensión.
En la siguiente tabla se explican las propiedades de configuración de enlace que se establecen en el archivo function.json.
Propiedad de function.json | Descripción |
---|---|
type | Se debe establecer en cosmosDBTrigger . |
direction | Se debe establecer en in . Este parámetro se establece automáticamente cuando se crea el desencadenador en Azure Portal. |
name | Nombre de la variable que se utiliza en el código de función y que representa la lista de documentos con los cambios. |
connection | Nombre de una configuración de aplicación o colección de configuraciones que especifica cómo conectarse a la cuenta de Azure Cosmos DB que se va a supervisar. Para obtener más información, consulte Conexiones. |
databaseName | Nombre de la base de datos de Azure Cosmos DB con el contenedor que se está supervisando. |
containerName | Nombre del contenedor que se está supervisando. |
leaseConnection | (Opcional) Nombre de una configuración de aplicación o contenedor de configuraciones que especifica cómo conectarse a la cuenta de Azure Cosmos DB que contiene la colección de concesiones. Si no se establece, se usa el valor connection . Este parámetro se establece automáticamente cuando se crea el enlace en el portal. La cadena de conexión para el contenedor de concesiones debe tener permisos de escritura. |
leaseDatabaseName | (Opcional) Nombre de la base de datos que contiene el contenedor que se usa para almacenar las concesiones. Si no se establece, se usa el valor de la configuración databaseName . |
leaseContainerName | (Opcional) Nombre del contenedor utilizado para almacenar concesiones. Si no se establece, se usa el valor leases . |
createLeaseContainerIfNotExists | (Opcional) Cuando se establece en true , el contenedor de concesiones se crea automáticamente cuando todavía no existe. El valor predeterminado es false . Al usar identidades de Microsoft Entra si establece el valor en true , la creación de contenedores no es una operación permitida y la función no podrá iniciarse. |
leasesContainerThroughput | (Opcional) Define la cantidad de unidades de solicitud que se asignan cuando se crea el contenedor de concesiones. Esta configuración solo se usa cuando createLeaseContainerIfNotExists se establece en true . Este parámetro se establece automáticamente cuando el enlace se crea con el portal. |
leaseContainerPrefix | (Opcional) Cuando se establece, el valor se agrega como prefijo a las concesiones creadas en el contenedor de concesiones para esta función. El uso de un prefijo permite que dos funciones de Azure Functions independientes compartan el mismo contenedor de concesiones con prefijos diferentes. |
feedPollDelay | (Opcional) El tiempo (en milisegundos) del retraso entre sondeos de una partición en busca de nuevos cambios en la fuente, después de que todos los cambios actuales se purguen. El valor predeterminado es de 5 000 milisegundos (o 5 segundos). |
leaseAcquireInterval | (Opcional) Al establecerse, define, en milisegundos, el intervalo para iniciar una tarea para calcular si las particiones se distribuyen uniformemente entre las instancias de host conocidas. El valor predeterminado es 13 000 (13 segundos). |
leaseExpirationInterval | (Opcional) Al establecerse, define, en milisegundos, el intervalo para el que se toma la concesión en una concesión que representa una partición. Si la concesión no se renueva dentro de este intervalo, expirará y la propiedad de la partición se moverá a otra instancia. El valor predeterminado es 60 000 (60 segundos). |
leaseRenewInterval | (Opcional) Al establecerse, define, en milisegundos, el intervalo de renovación para todas las concesiones para las particiones que mantiene una instancia actualmente. El valor predeterminado es 17 000 (17 segundos). |
maxItemsPerInvocation | (Opcional) Al establecerse, esta propiedad establece la cantidad máxima de elementos recibidos por llamada de función. Si las operaciones del contenedor supervisado se realizan mediante procedimientos almacenados, el ámbito de transacción se conserva al leer los elementos de la fuente de cambios. Como resultado, es posible que el número de elementos recibidos sea mayor que el valor especificado, de modo que los elementos que cambian en la misma transacción se devuelvan como parte de un lote atómico. |
startFromBeginning | (Opcional) Esta opción indica al desencadenador que lea los cambios desde el principio del historial de cambios del contenedor en lugar de comenzar en la hora actual. La lectura desde el principio solo funciona la primera vez que se inicia el desencadenador, ya que en las ejecuciones posteriores, los puntos de control ya están almacenados. Si esta opción se establece en true cuando ya hay concesiones creadas no tiene ningún efecto. |
startFromTime | (Opcional) Obtiene o establece la fecha y hora a partir de la que se va a inicializar la operación de lectura de fuente de cambios. El formato recomendado es ISO 8601 con el designador UTC, como 2021-02-16T14:19:29Z . Esto solo se usa para establecer el estado inicial del desencadenador. Una vez que el desencadenador tiene un estado de concesión, cambiar este valor no tiene ningún efecto. |
preferredLocations | (Opcional) Defina las ubicaciones preferidas (regiones) para las cuentas de base de datos con replicación geográfica en el servicio de Azure Cosmos DB. Los valores deben estar separados por comas. Por ejemplo, "Este de EE. UU., Centro-sur de EE. UU. Norte de Europa". |
En el ejemplo siguiente se muestra un enlace de desencadenador de Azure Cosmos DB en un archivo function.json y una función de script de C# que usa dicho enlace. La función escribe mensajes de registro cuando se agregan o modifican los registros de Azure Cosmos DB.
Estos son los datos de enlace del archivo function.json:
{
"type": "cosmosDBTrigger",
"name": "documents",
"direction": "in",
"leaseContainerName": "leases",
"connection": "<connection-app-setting>",
"databaseName": "Tasks",
"containerName": "Items",
"createLeaseContainerIfNotExists": true
}
Este es el código de script de C#:
using System;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
// Customize the model with your own desired properties
public class ToDoItem
{
public string id { get; set; }
public string Description { get; set; }
}
public static void Run(IReadOnlyList<ToDoItem> documents, ILogger log)
{
log.LogInformation("Documents modified " + documents.Count);
log.LogInformation("First document Id " + documents[0].id);
}
Entrada de Azure Cosmos DB v2
En esta sección se describe la compatibilidad solo para la versión 4.x+ de la extensión.
En la siguiente tabla se explican las propiedades de configuración de enlace que se establecen en el archivo function.json.
Propiedad de function.json | Descripción |
---|---|
type | Se debe establecer en cosmosDB . |
direction | Se debe establecer en in . |
name | Nombre de la variable que se utiliza en el código de función y que representa la lista de documentos con los cambios. |
connection | Nombre de una configuración de aplicación o contenedor de configuraciones que especifica cómo conectarse a la cuenta de Azure Cosmos DB que se va a supervisar. Para obtener más información, consulte Conexiones. |
databaseName | Nombre de la base de datos de Azure Cosmos DB con el contenedor que se está supervisando. |
containerName | Nombre del contenedor que se está supervisando. |
partitionKey | Especifica el valor de la clave de partición para la búsqueda. Puede incluir parámetros de enlace. Se requiere para las búsquedas en contenedores con particiones. |
id | Identificador del documento que se va a recuperar. Esta propiedad es compatible con expresiones de enlace. No establezca las propiedades id y sqlQuery a la vez. Si no establece alguna de ellas, se recupera todo el contenedor. |
sqlQuery | Consulta SQL de Azure Cosmos DB que se usa para recuperar varios documentos. La propiedad es compatible con los enlaces en tiempo de ejecución, como en este ejemplo: SELECT * FROM c where c.departmentId = {departmentId} . No establezca las propiedades id y sqlQuery a la vez. Si no establece alguna de ellas, se recupera todo el contenedor. |
preferredLocations | (Opcional) Defina las ubicaciones preferidas (regiones) para las cuentas de base de datos con replicación geográfica en el servicio de Azure Cosmos DB. Los valores deben estar separados por comas. Por ejemplo, East US,South Central US,North Europe . |
En esta sección se incluyen los ejemplos siguientes:
- Desencadenador de cola, buscar identificador de una cadena
- Desencadenador de colas, obtener varios documentos, mediante SqlQuery
- Desencadenador de HTTP, buscar identificador de cadena de consulta
- Desencadenador de HTTP, buscar identificador de datos de ruta
- Desencadenador de HTTP, obtener varios documentos, mediante SqlQuery
- Desencadenador de HTTP, obtener varios documentos, mediante DocumentClient
Los ejemplos de desencadenador de HTTP hacen referencia a un tipo simple ToDoItem
:
namespace CosmosDBSamplesV2
{
public class ToDoItem
{
public string Id { get; set; }
public string Description { get; set; }
}
}
Desencadenador de cola, buscar identificador a partir de una cadena
En el ejemplo siguiente se muestra un enlace de entrada de Azure Cosmos DB en un archivo function.json y una función de script de C# que usa el enlace. La función lee un solo documento y actualiza el valor de texto del documento.
Estos son los datos de enlace del archivo function.json:
{
"name": "inputDocument",
"type": "cosmosDB",
"databaseName": "MyDatabase",
"collectionName": "MyCollection",
"id" : "{queueTrigger}",
"partitionKey": "{partition key value}",
"connectionStringSetting": "MyAccount_COSMOSDB",
"direction": "in"
}
Este es el código de script de C#:
using System;
// Change input document contents using Azure Cosmos DB input binding
public static void Run(string myQueueItem, dynamic inputDocument)
{
inputDocument.text = "This has changed.";
}
Desencadenador de colas, obtener varios documentos mediante SqlQuery
En el ejemplo siguiente se muestra un enlace de entrada de Azure Cosmos DB en un archivo function.json y una función de script de C# que usa el enlace. La función recupera varios documentos especificados por una consulta SQL con un desencadenador de cola para personalizar los parámetros de la consulta.
El desencadenador de cola proporciona un parámetro departmentId
. Un mensaje de la cola de { "departmentId" : "Finance" }
devolvería todos los registros para el departamento de finanzas.
Estos son los datos de enlace del archivo function.json:
{
"name": "documents",
"type": "cosmosDB",
"direction": "in",
"databaseName": "MyDb",
"collectionName": "MyCollection",
"sqlQuery": "SELECT * from c where c.departmentId = {departmentId}",
"connectionStringSetting": "CosmosDBConnection"
}
Este es el código de script de C#:
public static void Run(QueuePayload myQueueItem, IEnumerable<dynamic> documents)
{
foreach (var doc in documents)
{
// operate on each document
}
}
public class QueuePayload
{
public string departmentId { get; set; }
}
Desencadenador de HTTP, buscar identificador a partir de una cadena de consulta
En el ejemplo siguiente se muestra una función de script de C# que recupera un documento individual. La función la desencadena una solicitud HTTP que utiliza una cadena de consulta para especificar el identificador y el valor de la clave de partición que se van a buscar. El identificador y el valor de la clave de partición se utilizan para recuperar un documento ToDoItem
de la base de datos y colección especificadas.
Este es el archivo function.json:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"type": "cosmosDB",
"name": "toDoItem",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connectionStringSetting": "CosmosDBConnection",
"direction": "in",
"Id": "{Query.id}",
"PartitionKey" : "{Query.partitionKeyValue}"
}
],
"disabled": false
}
Este es el código de script de C#:
using System.Net;
using Microsoft.Extensions.Logging;
public static HttpResponseMessage Run(HttpRequestMessage req, ToDoItem toDoItem, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
if (toDoItem == null)
{
log.LogInformation($"ToDo item not found");
}
else
{
log.LogInformation($"Found ToDo item, Description={toDoItem.Description}");
}
return req.CreateResponse(HttpStatusCode.OK);
}
Desencadenador de HTTP, buscar identificador a partir de datos de ruta
En el ejemplo siguiente se muestra una función de script de C# que recupera un documento individual. La función la desencadena una solicitud HTTP que utiliza datos de ruta para especificar el identificador y el valor de la clave de partición que se van a buscar. El identificador y el valor de la clave de partición se utilizan para recuperar un documento ToDoItem
de la base de datos y colección especificadas.
Este es el archivo function.json:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
],
"route":"todoitems/{partitionKeyValue}/{id}"
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"type": "cosmosDB",
"name": "toDoItem",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connectionStringSetting": "CosmosDBConnection",
"direction": "in",
"id": "{id}",
"partitionKey": "{partitionKeyValue}"
}
],
"disabled": false
}
Este es el código de script de C#:
using System.Net;
using Microsoft.Extensions.Logging;
public static HttpResponseMessage Run(HttpRequestMessage req, ToDoItem toDoItem, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
if (toDoItem == null)
{
log.LogInformation($"ToDo item not found");
}
else
{
log.LogInformation($"Found ToDo item, Description={toDoItem.Description}");
}
return req.CreateResponse(HttpStatusCode.OK);
}
Desencadenador de HTTP, obtener varios documentos mediante SqlQuery
En el ejemplo siguiente se muestra una función de script de C# que recupera una lista de documentos. La función la desencadena una solicitud HTTP. La consulta se especifica en la propiedad del atributo SqlQuery
.
Este es el archivo function.json:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"type": "cosmosDB",
"name": "toDoItems",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connectionStringSetting": "CosmosDBConnection",
"direction": "in",
"sqlQuery": "SELECT top 2 * FROM c order by c._ts desc"
}
],
"disabled": false
}
Este es el código de script de C#:
using System.Net;
using Microsoft.Extensions.Logging;
public static HttpResponseMessage Run(HttpRequestMessage req, IEnumerable<ToDoItem> toDoItems, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
foreach (ToDoItem toDoItem in toDoItems)
{
log.LogInformation(toDoItem.Description);
}
return req.CreateResponse(HttpStatusCode.OK);
}
Desencadenador de HTTP, obtener varios documentos mediante DocumentClient
En el ejemplo siguiente se muestra una función de script de C# que recupera una lista de documentos. La función la desencadena una solicitud HTTP. El código usa una instancia de DocumentClient
que proporciona el enlace de Azure Cosmos DB para leer una lista de documentos. La instancia de DocumentClient
también se puede usar para las operaciones de escritura.
Este es el archivo function.json:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"type": "cosmosDB",
"name": "client",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connectionStringSetting": "CosmosDBConnection",
"direction": "inout"
}
],
"disabled": false
}
Este es el código de script de C#:
#r "Microsoft.Azure.Documents.Client"
using System.Net;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Microsoft.Extensions.Logging;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, DocumentClient client, ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
Uri collectionUri = UriFactory.CreateDocumentCollectionUri("ToDoItems", "Items");
string searchterm = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "searchterm", true) == 0)
.Value;
if (searchterm == null)
{
return req.CreateResponse(HttpStatusCode.NotFound);
}
log.LogInformation($"Searching for word: {searchterm} using Uri: {collectionUri.ToString()}");
IDocumentQuery<ToDoItem> query = client.CreateDocumentQuery<ToDoItem>(collectionUri)
.Where(p => p.Description.Contains(searchterm))
.AsDocumentQuery();
while (query.HasMoreResults)
{
foreach (ToDoItem result in await query.ExecuteNextAsync())
{
log.LogInformation(result.Description);
}
}
return req.CreateResponse(HttpStatusCode.OK);
}
Salida de Azure Cosmos DB v2
En esta sección se describe la compatibilidad solo para la versión 4.x+ de la extensión.
En la siguiente tabla se explican las propiedades de configuración de enlace que se establecen en el archivo function.json.
Propiedad de function.json | Descripción |
---|---|
connection | Nombre de una configuración de aplicación o colección de configuraciones que especifica cómo conectarse a la cuenta de Azure Cosmos DB que se va a supervisar. Para obtener más información, consulte Conexiones. |
databaseName | Nombre de la base de datos de Azure Cosmos DB con el contenedor que se está supervisando. |
containerName | Nombre del contenedor que se está supervisando. |
createIfNotExists | Valor booleano que indica si el contenedor se ha creado si no existía. El valor predeterminado es false porque los contenedores nuevos se crean con rendimiento reservado, lo que afecta al costo. Consulte la página de preciospara obtener más información. |
partitionKey | Cuando el valor de createIfNotExists es true, define la ruta de la clave de partición para el contenedor creado. Puede incluir parámetros de enlace. |
containerThroughput | Cuando el valor de createIfNotExists es true, define el rendimiento del contenedor creado. |
preferredLocations | (Opcional) Defina las ubicaciones preferidas (regiones) para las cuentas de base de datos con replicación geográfica en el servicio de Azure Cosmos DB. Los valores deben estar separados por comas. Por ejemplo, East US,South Central US,North Europe . |
En esta sección se incluyen los ejemplos siguientes:
- Desencadenador de cola, escribir un documento
- Desencadenador de cola, escribir documentos mediante IAsyncCollector
Desencadenador de cola, escribir un documento
En el ejemplo siguiente se muestra un enlace de salida de Azure Cosmos DB en un archivo function.json y una función de script de C# que usa el enlace. La función usa un enlace de entrada de cola para una cola que recibe JSON en el formato siguiente:
{
"name": "John Henry",
"employeeId": "123456",
"address": "A town nearby"
}
La función crea documentos de Azure Cosmos DB en el formato siguiente para cada registro:
{
"id": "John Henry-123456",
"name": "John Henry",
"employeeId": "123456",
"address": "A town nearby"
}
Estos son los datos de enlace del archivo function.json:
{
"name": "employeeDocument",
"type": "cosmosDB",
"databaseName": "MyDatabase",
"collectionName": "MyCollection",
"createIfNotExists": true,
"connectionStringSetting": "MyAccount_COSMOSDB",
"direction": "out"
}
Este es el código de script de C#:
#r "Newtonsoft.Json"
using Microsoft.Azure.WebJobs.Host;
using Newtonsoft.Json.Linq;
using Microsoft.Extensions.Logging;
public static void Run(string myQueueItem, out object employeeDocument, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
dynamic employee = JObject.Parse(myQueueItem);
employeeDocument = new {
id = employee.name + "-" + employee.employeeId,
name = employee.name,
employeeId = employee.employeeId,
address = employee.address
};
}
Desencadenador de cola, escribir documentos mediante IAsyncCollector
Para crear varios documentos, puede enlazar a ICollector<T>
o IAsyncCollector<T>
, donde T
es uno de los tipos admitidos.
En este ejemplo se hace referencia a un tipo simple ToDoItem
:
namespace CosmosDBSamplesV2
{
public class ToDoItem
{
public string id { get; set; }
public string Description { get; set; }
}
}
Este es el archivo function.json:
{
"bindings": [
{
"name": "toDoItemsIn",
"type": "queueTrigger",
"direction": "in",
"queueName": "todoqueueforwritemulti",
"connectionStringSetting": "AzureWebJobsStorage"
},
{
"type": "cosmosDB",
"name": "toDoItemsOut",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connectionStringSetting": "CosmosDBConnection",
"direction": "out"
}
],
"disabled": false
}
Este es el código de script de C#:
using System;
using Microsoft.Extensions.Logging;
public static async Task Run(ToDoItem[] toDoItemsIn, IAsyncCollector<ToDoItem> toDoItemsOut, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed {toDoItemsIn?.Length} items");
foreach (ToDoItem toDoItem in toDoItemsIn)
{
log.LogInformation($"Description={toDoItem.Description}");
await toDoItemsOut.AddAsync(toDoItem);
}
}
Desencadenador de Azure Cosmos DB v1
En el ejemplo siguiente se muestra un enlace de desencadenador de Azure Cosmos DB en un archivo function.json y una función de script de C# que usa dicho enlace. La función escribe mensajes de registro cuando se modifican los registros de Azure Cosmos DB.
Estos son los datos de enlace del archivo function.json:
{
"type": "cosmosDBTrigger",
"name": "documents",
"direction": "in",
"leaseCollectionName": "leases",
"connectionStringSetting": "<connection-app-setting>",
"databaseName": "Tasks",
"collectionName": "Items",
"createLeaseCollectionIfNotExists": true
}
Este es el código de script de C#:
#r "Microsoft.Azure.Documents.Client"
using System;
using Microsoft.Azure.Documents;
using System.Collections.Generic;
public static void Run(IReadOnlyList<Document> documents, TraceWriter log)
{
log.Info("Documents modified " + documents.Count);
log.Info("First document Id " + documents[0].Id);
}
Entrada de Azure Cosmos DB v1
En esta sección se incluyen los ejemplos siguientes:
- Desencadenador de cola, buscar identificador de una cadena
- Desencadenador de colas, obtener varios documentos, mediante SqlQuery
- Desencadenador de HTTP, buscar identificador de cadena de consulta
- Desencadenador de HTTP, buscar identificador de datos de ruta
- Desencadenador de HTTP, obtener varios documentos, mediante SqlQuery
- Desencadenador de HTTP, obtener varios documentos, mediante DocumentClient
Los ejemplos de desencadenador de HTTP hacen referencia a un tipo simple ToDoItem
:
namespace CosmosDBSamplesV1
{
public class ToDoItem
{
public string Id { get; set; }
public string Description { get; set; }
}
}
Desencadenador de cola, buscar identificador a partir de una cadena
En el ejemplo siguiente se muestra un enlace de entrada de Azure Cosmos DB en un archivo function.json y una función de script de C# que usa el enlace. La función lee un solo documento y actualiza el valor de texto del documento.
Estos son los datos de enlace del archivo function.json:
{
"name": "inputDocument",
"type": "documentDB",
"databaseName": "MyDatabase",
"collectionName": "MyCollection",
"id" : "{queueTrigger}",
"partitionKey": "{partition key value}",
"connection": "MyAccount_COSMOSDB",
"direction": "in"
}
Este es el código de script de C#:
using System;
// Change input document contents using Azure Cosmos DB input binding
public static void Run(string myQueueItem, dynamic inputDocument)
{
inputDocument.text = "This has changed.";
}
Desencadenador de colas, obtener varios documentos mediante SqlQuery
En el ejemplo siguiente se muestra un enlace de entrada de Azure Cosmos DB en un archivo function.json y una función de script de C# que usa el enlace. La función recupera varios documentos especificados por una consulta SQL con un desencadenador de cola para personalizar los parámetros de la consulta.
El desencadenador de cola proporciona un parámetro departmentId
. Un mensaje de la cola de { "departmentId" : "Finance" }
devolvería todos los registros para el departamento de finanzas.
Estos son los datos de enlace del archivo function.json:
{
"name": "documents",
"type": "documentdb",
"direction": "in",
"databaseName": "MyDb",
"collectionName": "MyCollection",
"sqlQuery": "SELECT * from c where c.departmentId = {departmentId}",
"connection": "CosmosDBConnection"
}
Este es el código de script de C#:
public static void Run(QueuePayload myQueueItem, IEnumerable<dynamic> documents)
{
foreach (var doc in documents)
{
// operate on each document
}
}
public class QueuePayload
{
public string departmentId { get; set; }
}
Desencadenador de HTTP, buscar identificador a partir de una cadena de consulta
En el ejemplo siguiente se muestra una función de script de C# que recupera un documento individual. La función la desencadena una solicitud HTTP que utiliza una cadena de consulta para especificar el identificador que se va a buscar. Dicho identificador se usa para recuperar un documento de ToDoItem
de la base de datos y colección especificadas.
Este es el archivo function.json:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"type": "documentDB",
"name": "toDoItem",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connection": "CosmosDBConnection",
"direction": "in",
"Id": "{Query.id}"
}
],
"disabled": true
}
Este es el código de script de C#:
using System.Net;
public static HttpResponseMessage Run(HttpRequestMessage req, ToDoItem toDoItem, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
if (toDoItem == null)
{
log.Info($"ToDo item not found");
}
else
{
log.Info($"Found ToDo item, Description={toDoItem.Description}");
}
return req.CreateResponse(HttpStatusCode.OK);
}
Desencadenador de HTTP, buscar identificador a partir de datos de ruta
En el ejemplo siguiente se muestra una función de script de C# que recupera un documento individual. La función la desencadena una solicitud HTTP que utiliza los datos de la ruta para especificar el identificador que se va a buscar. Dicho identificador se usa para recuperar un documento de ToDoItem
de la base de datos y colección especificadas.
Este es el archivo function.json:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
],
"route":"todoitems/{id}"
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"type": "documentDB",
"name": "toDoItem",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connection": "CosmosDBConnection",
"direction": "in",
"Id": "{id}"
}
],
"disabled": false
}
Este es el código de script de C#:
using System.Net;
public static HttpResponseMessage Run(HttpRequestMessage req, ToDoItem toDoItem, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
if (toDoItem == null)
{
log.Info($"ToDo item not found");
}
else
{
log.Info($"Found ToDo item, Description={toDoItem.Description}");
}
return req.CreateResponse(HttpStatusCode.OK);
}
Desencadenador de HTTP, obtener varios documentos mediante SqlQuery
En el ejemplo siguiente se muestra una función de script de C# que recupera una lista de documentos. La función la desencadena una solicitud HTTP. La consulta se especifica en la propiedad del atributo SqlQuery
.
Este es el archivo function.json:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"type": "documentDB",
"name": "toDoItems",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connection": "CosmosDBConnection",
"direction": "in",
"sqlQuery": "SELECT top 2 * FROM c order by c._ts desc"
}
],
"disabled": false
}
Este es el código de script de C#:
using System.Net;
public static HttpResponseMessage Run(HttpRequestMessage req, IEnumerable<ToDoItem> toDoItems, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
foreach (ToDoItem toDoItem in toDoItems)
{
log.Info(toDoItem.Description);
}
return req.CreateResponse(HttpStatusCode.OK);
}
Desencadenador de HTTP, obtener varios documentos mediante DocumentClient
En el ejemplo siguiente se muestra una función de script de C# que recupera una lista de documentos. La función la desencadena una solicitud HTTP. El código usa una instancia de DocumentClient
que proporciona el enlace de Azure Cosmos DB para leer una lista de documentos. La instancia de DocumentClient
también se puede usar para las operaciones de escritura.
Este es el archivo function.json:
{
"bindings": [
{
"authLevel": "anonymous",
"name": "req",
"type": "httpTrigger",
"direction": "in",
"methods": [
"get",
"post"
]
},
{
"name": "$return",
"type": "http",
"direction": "out"
},
{
"type": "documentDB",
"name": "client",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connection": "CosmosDBConnection",
"direction": "inout"
}
],
"disabled": false
}
Este es el código de script de C#:
#r "Microsoft.Azure.Documents.Client"
using System.Net;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, DocumentClient client, TraceWriter log)
{
log.Info("C# HTTP trigger function processed a request.");
Uri collectionUri = UriFactory.CreateDocumentCollectionUri("ToDoItems", "Items");
string searchterm = req.GetQueryNameValuePairs()
.FirstOrDefault(q => string.Compare(q.Key, "searchterm", true) == 0)
.Value;
if (searchterm == null)
{
return req.CreateResponse(HttpStatusCode.NotFound);
}
log.Info($"Searching for word: {searchterm} using Uri: {collectionUri.ToString()}");
IDocumentQuery<ToDoItem> query = client.CreateDocumentQuery<ToDoItem>(collectionUri)
.Where(p => p.Description.Contains(searchterm))
.AsDocumentQuery();
while (query.HasMoreResults)
{
foreach (ToDoItem result in await query.ExecuteNextAsync())
{
log.Info(result.Description);
}
}
return req.CreateResponse(HttpStatusCode.OK);
}
Salida de Azure Cosmos DB v1
En esta sección se incluyen los ejemplos siguientes:
- Desencadenador de cola, escribir un documento
- Desencadenador de cola, escribir documentos mediante
IAsyncCollector
Desencadenador de cola, escribir un documento
En el ejemplo siguiente se muestra un enlace de salida de Azure Cosmos DB en un archivo function.json y una función de script de C# que usa el enlace. La función usa un enlace de entrada de cola para una cola que recibe JSON en el formato siguiente:
{
"name": "John Henry",
"employeeId": "123456",
"address": "A town nearby"
}
La función crea documentos de Azure Cosmos DB en el formato siguiente para cada registro:
{
"id": "John Henry-123456",
"name": "John Henry",
"employeeId": "123456",
"address": "A town nearby"
}
Estos son los datos de enlace del archivo function.json:
{
"name": "employeeDocument",
"type": "documentDB",
"databaseName": "MyDatabase",
"collectionName": "MyCollection",
"createIfNotExists": true,
"connection": "MyAccount_COSMOSDB",
"direction": "out"
}
Este es el código de script de C#:
#r "Newtonsoft.Json"
using Microsoft.Azure.WebJobs.Host;
using Newtonsoft.Json.Linq;
public static void Run(string myQueueItem, out object employeeDocument, TraceWriter log)
{
log.Info($"C# Queue trigger function processed: {myQueueItem}");
dynamic employee = JObject.Parse(myQueueItem);
employeeDocument = new {
id = employee.name + "-" + employee.employeeId,
name = employee.name,
employeeId = employee.employeeId,
address = employee.address
};
}
Desencadenador de cola, escribir documentos mediante IAsyncCollector
Para crear varios documentos, puede enlazar a ICollector<T>
o IAsyncCollector<T>
, donde T
es uno de los tipos admitidos.
En este ejemplo se hace referencia a un tipo simple ToDoItem
:
namespace CosmosDBSamplesV1
{
public class ToDoItem
{
public string Id { get; set; }
public string Description { get; set; }
}
}
Este es el archivo function.json:
{
"bindings": [
{
"name": "toDoItemsIn",
"type": "queueTrigger",
"direction": "in",
"queueName": "todoqueueforwritemulti",
"connection": "AzureWebJobsStorage"
},
{
"type": "documentDB",
"name": "toDoItemsOut",
"databaseName": "ToDoItems",
"collectionName": "Items",
"connection": "CosmosDBConnection",
"direction": "out"
}
],
"disabled": false
}
Este es el código de script de C#:
using System;
public static async Task Run(ToDoItem[] toDoItemsIn, IAsyncCollector<ToDoItem> toDoItemsOut, TraceWriter log)
{
log.Info($"C# Queue trigger function processed {toDoItemsIn?.Length} items");
foreach (ToDoItem toDoItem in toDoItemsIn)
{
log.Info($"Description={toDoItem.Description}");
await toDoItemsOut.AddAsync(toDoItem);
}
}
Desencadenador de Azure SQL
Hay disponibles más ejemplos del desencadenador de Azure SQL en el repositorio de GitHub.
En este ejemplo se hace referencia a una clase ToDoItem
y una tabla de base de datos correspondiente:
namespace AzureSQL.ToDo
{
public class ToDoItem
{
public Guid Id { get; set; }
public int? order { get; set; }
public string title { get; set; }
public string url { get; set; }
public bool? completed { get; set; }
}
}
CREATE TABLE dbo.ToDo (
[Id] UNIQUEIDENTIFIER PRIMARY KEY,
[order] INT NULL,
[title] NVARCHAR(200) NOT NULL,
[url] NVARCHAR(200) NOT NULL,
[completed] BIT NOT NULL
);
El seguimiento de cambios está habilitado en la base de datos y en la tabla:
ALTER DATABASE [SampleDatabase]
SET CHANGE_TRACKING = ON
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON);
ALTER TABLE [dbo].[ToDo]
ENABLE CHANGE_TRACKING;
El desencadenador de Azure SQL enlaza a IReadOnlyList<SqlChange<T>>
, una lista de objetos SqlChange
, cada uno con 2 propiedades:
- Item: el elemento que ha cambiado. El tipo del elemento debe seguir el esquema de tabla tal como se ve en la clase
ToDoItem
. - Operation: un valor de la enumeración
SqlChangeOperation
. Los valores posibles sonInsert
,Update
yDelete
.
En el ejemplo siguiente, se muestra un desencadenador de SQL en un archivo function.json y una función de script de C# que se invocará cuando haya cambios en la tabla ToDo
:
A continuación, se muestran los datos de enlace del archivo function.json:
{
"name": "todoChanges",
"type": "sqlTrigger",
"direction": "in",
"tableName": "dbo.ToDo",
"connectionStringSetting": "SqlConnectionString"
}
A continuación, se muestra la función de script de C#:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
public static void Run(IReadOnlyList<SqlChange<ToDoItem>> todoChanges, ILogger log)
{
log.LogInformation($"C# SQL trigger function processed a request.");
foreach (SqlChange<ToDoItem> change in todoChanges)
{
ToDoItem toDoItem = change.Item;
log.LogInformation($"Change operation: {change.Operation}");
log.LogInformation($"Id: {toDoItem.Id}, Title: {toDoItem.title}, Url: {toDoItem.url}, Completed: {toDoItem.completed}");
}
}
Entrada de Azure SQL
Hay disponibles más ejemplos para el enlace de entrada de Azure SQL en el repositorio de GitHub.
En esta sección se incluyen los ejemplos siguientes:
- Desencadenador HTTP, obtención de fila por id. de la cadena de consulta
- Desencadenador HTTP, eliminación de filas
En este ejemplo se hace referencia a una clase ToDoItem
y una tabla de base de datos correspondiente:
namespace AzureSQL.ToDo
{
public class ToDoItem
{
public Guid Id { get; set; }
public int? order { get; set; }
public string title { get; set; }
public string url { get; set; }
public bool? completed { get; set; }
}
}
CREATE TABLE dbo.ToDo (
[Id] UNIQUEIDENTIFIER PRIMARY KEY,
[order] INT NULL,
[title] NVARCHAR(200) NOT NULL,
[url] NVARCHAR(200) NOT NULL,
[completed] BIT NOT NULL
);
Desencadenador HTTP, obtención de fila por id. de la cadena de consulta
En el ejemplo siguiente se muestra un enlace de entrada de Azure SQL en un archivo function.json y una función de script de C# que usa el enlace. La función la desencadena una solicitud HTTP que utiliza una cadena de consulta para especificar el identificador. Ese identificador se usa para recuperar un registro ToDoItem
con la consulta especificada.
Nota
El parámetro de la cadena de consulta HTTP distingue mayúsculas de minúsculas.
Estos son los datos de enlace del archivo function.json:
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"name": "todoItem",
"type": "sql",
"direction": "in",
"commandText": "select [Id], [order], [title], [url], [completed] from dbo.ToDo where Id = @Id",
"commandType": "Text",
"parameters": "@Id = {Query.id}",
"connectionStringSetting": "SqlConnectionString"
}
Este es el código de script de C#:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System.Collections.Generic;
public static IActionResult Run(HttpRequest req, ILogger log, IEnumerable<ToDoItem> todoItem)
{
return new OkObjectResult(todoItem);
}
Desencadenador HTTP, eliminación de filas
En el ejemplo siguiente se muestra un enlace de entrada Azure SQL en un archivo function.json y una función de script C# que usa el enlace para ejecutar un procedimiento almacenado con entrada del parámetro de consulta de solicitud HTTP. En este ejemplo, el procedimiento almacenado elimina un único registro o todos los registros en función del valor del parámetro.
El procedimiento almacenado dbo.DeleteToDo
debe crearse en la base de datos SQL.
CREATE PROCEDURE [dbo].[DeleteToDo]
@Id NVARCHAR(100)
AS
DECLARE @UID UNIQUEIDENTIFIER = TRY_CAST(@ID AS UNIQUEIDENTIFIER)
IF @UId IS NOT NULL AND @Id != ''
BEGIN
DELETE FROM dbo.ToDo WHERE Id = @UID
END
ELSE
BEGIN
DELETE FROM dbo.ToDo WHERE @ID = ''
END
SELECT [Id], [order], [title], [url], [completed] FROM dbo.ToDo
GO
Estos son los datos de enlace del archivo function.json:
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"name": "todoItems",
"type": "sql",
"direction": "in",
"commandText": "DeleteToDo",
"commandType": "StoredProcedure",
"parameters": "@Id = {Query.id}",
"connectionStringSetting": "SqlConnectionString"
}
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
namespace AzureSQL.ToDo
{
public static class DeleteToDo
{
// delete all items or a specific item from querystring
// returns remaining items
// uses input binding with a stored procedure DeleteToDo to delete items and return remaining items
[FunctionName("DeleteToDo")]
public static IActionResult Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "delete", Route = "DeleteFunction")] HttpRequest req,
ILogger log,
[Sql(commandText: "DeleteToDo", commandType: System.Data.CommandType.StoredProcedure,
parameters: "@Id={Query.id}", connectionStringSetting: "SqlConnectionString")]
IEnumerable<ToDoItem> toDoItems)
{
return new OkObjectResult(toDoItems);
}
}
}
Este es el código de script de C#:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System.Collections.Generic;
public static IActionResult Run(HttpRequest req, ILogger log, IEnumerable<ToDoItem> todoItems)
{
return new OkObjectResult(todoItems);
}
Salida de Azure SQL
Hay disponibles más ejemplos para el enlace de salida de Azure SQL en el repositorio de GitHub.
En esta sección se incluyen los ejemplos siguientes:
- Desencadenador HTTP, escritura de registros en una tabla
- Desencadenador HTTP, escritura en dos tablas
En este ejemplo se hace referencia a una clase ToDoItem
y una tabla de base de datos correspondiente:
namespace AzureSQL.ToDo
{
public class ToDoItem
{
public Guid Id { get; set; }
public int? order { get; set; }
public string title { get; set; }
public string url { get; set; }
public bool? completed { get; set; }
}
}
CREATE TABLE dbo.ToDo (
[Id] UNIQUEIDENTIFIER PRIMARY KEY,
[order] INT NULL,
[title] NVARCHAR(200) NOT NULL,
[url] NVARCHAR(200) NOT NULL,
[completed] BIT NOT NULL
);
Desencadenador HTTP, escritura de registros en una tabla
En el ejemplo siguiente se muestra un enlace de salida de SQL en un archivo function.json y una función de C# que agrega registros a una tabla mediante los datos proporcionados en una solicitud de HTTP POST como un cuerpo JSON.
A continuación, se muestran los datos de enlace del archivo function.json:
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"name": "todoItem",
"type": "sql",
"direction": "out",
"commandText": "dbo.ToDo",
"connectionStringSetting": "SqlConnectionString"
}
A continuación, se muestra un ejemplo de código de script C#:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
public static IActionResult Run(HttpRequest req, ILogger log, out ToDoItem todoItem)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string requestBody = new StreamReader(req.Body).ReadToEnd();
todoItem = JsonConvert.DeserializeObject<ToDoItem>(requestBody);
return new OkObjectResult(todoItem);
}
Desencadenador HTTP, escritura en dos tablas
En el ejemplo siguiente se muestra un enlace de salida de SQL en un archivo function.json y una función de C# que agrega registros a una base de datos en dos tablas diferentes (dbo.ToDo
y dbo.RequestLog
), mediante los datos proporcionados en una solicitud de HTTP POST como un cuerpo JSON y varios enlaces de salida.
La segunda tabla, dbo.RequestLog
, corresponde a la siguiente definición:
CREATE TABLE dbo.RequestLog (
Id int identity(1,1) primary key,
RequestTimeStamp datetime2 not null,
ItemCount int not null
)
A continuación se muestran los datos de enlace del archivo function.json:
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"name": "todoItem",
"type": "sql",
"direction": "out",
"commandText": "dbo.ToDo",
"connectionStringSetting": "SqlConnectionString"
},
{
"name": "requestLog",
"type": "sql",
"direction": "out",
"commandText": "dbo.RequestLog",
"connectionStringSetting": "SqlConnectionString"
}
A continuación, se muestra un ejemplo de código de script C#:
#r "Newtonsoft.Json"
using System.Net;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
public static IActionResult Run(HttpRequest req, ILogger log, out ToDoItem todoItem, out RequestLog requestLog)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string requestBody = new StreamReader(req.Body).ReadToEnd();
todoItem = JsonConvert.DeserializeObject<ToDoItem>(requestBody);
requestLog = new RequestLog();
requestLog.RequestTimeStamp = DateTime.Now;
requestLog.ItemCount = 1;
return new OkObjectResult(todoItem);
}
public class RequestLog {
public DateTime RequestTimeStamp { get; set; }
public int ItemCount { get; set; }
}
Salida de RabbitMQ
En el ejemplo siguiente se muestra un enlace de salida de RabbitMQ en un archivo function.json y una función de script de C# que usa el enlace. La función lee el mensaje desde un desencadenador HTTP y lo envía a la cola de RabbitMQ.
Estos son los datos de enlace del archivo function.json:
{
"bindings": [
{
"type": "httpTrigger",
"direction": "in",
"authLevel": "function",
"name": "input",
"methods": [
"get",
"post"
]
},
{
"type": "rabbitMQ",
"name": "outputMessage",
"queueName": "outputQueue",
"connectionStringSetting": "rabbitMQConnectionAppSetting",
"direction": "out"
}
]
}
Este es el código de script de C#:
using System;
using Microsoft.Extensions.Logging;
public static void Run(string input, out string outputMessage, ILogger log)
{
log.LogInformation(input);
outputMessage = input;
}
Salida de SendGrid
En el ejemplo siguiente se muestra un enlace de salida de SendGrid en un archivo function.json y una función de script de C# que usa el enlace.
Estos son los datos de enlace del archivo function.json:
{
"bindings": [
{
"type": "queueTrigger",
"name": "mymsg",
"queueName": "myqueue",
"connection": "AzureWebJobsStorage",
"direction": "in"
},
{
"type": "sendGrid",
"name": "$return",
"direction": "out",
"apiKey": "SendGridAPIKeyAsAppSetting",
"from": "{FromEmail}",
"to": "{ToEmail}"
}
]
}
Este es el código de script de C#:
#r "SendGrid"
using System;
using SendGrid.Helpers.Mail;
using Microsoft.Azure.WebJobs.Host;
public static SendGridMessage Run(Message mymsg, ILogger log)
{
SendGridMessage message = new SendGridMessage()
{
Subject = $"{mymsg.Subject}"
};
message.AddContent("text/plain", $"{mymsg.Content}");
return message;
}
public class Message
{
public string ToEmail { get; set; }
public string FromEmail { get; set; }
public string Subject { get; set; }
public string Content { get; set; }
}
Desencadenador de SignalR
Estos son datos de enlace de ejemplo del archivo function.json:
{
"type": "signalRTrigger",
"name": "invocation",
"hubName": "SignalRTest",
"category": "messages",
"event": "SendMessage",
"parameterNames": [
"message"
],
"direction": "in"
}
Y este es el código:
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using System;
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
using Microsoft.Extensions.Logging;
public static void Run(InvocationContext invocation, string message, ILogger logger)
{
logger.LogInformation($"Receive {message} from {invocationContext.ConnectionId}.");
}
Entrada de SignalR
En el ejemplo siguiente se muestra un enlace de entrada de la información de la conexión de SignalR en un archivo function.json y una función de script de C# que usa el enlace para devolver la información de conexión.
Estos son los datos de enlace del archivo function.json:
Function.json de ejemplo:
{
"type": "signalRConnectionInfo",
"name": "connectionInfo",
"hubName": "chat",
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
"direction": "in"
}
Este es el código de script de C#:
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
public static SignalRConnectionInfo Run(HttpRequest req, SignalRConnectionInfo connectionInfo)
{
return connectionInfo;
}
Puede establecer la propiedad userId
del enlace en el valor de cualquier encabezado mediante una expresión de enlace: {headers.x-ms-client-principal-id}
o {headers.x-ms-client-principal-name}
.
Function.json de ejemplo:
{
"type": "signalRConnectionInfo",
"name": "connectionInfo",
"hubName": "chat",
"userId": "{headers.x-ms-client-principal-id}",
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
"direction": "in"
}
Este es el código de script de C#:
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
public static SignalRConnectionInfo Run(HttpRequest req, SignalRConnectionInfo connectionInfo)
{
// connectionInfo contains an access key token with a name identifier
// claim set to the authenticated user
return connectionInfo;
}
Salida de SignalR
Estos son los datos de enlace del archivo function.json:
Function.json de ejemplo:
{
"type": "signalR",
"name": "signalRMessages",
"hubName": "<hub_name>",
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
"direction": "out"
}
Este es el código de script de C#:
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
public static Task Run(
object message,
IAsyncCollector<SignalRMessage> signalRMessages)
{
return signalRMessages.AddAsync(
new SignalRMessage
{
Target = "newMessage",
Arguments = new [] { message }
});
}
Solo se pueden enviar mensajes a las conexiones que se hayan autenticado en un usuario mediante el establecimiento de UserID en el mensaje de SignalR.
Function.json de ejemplo:
{
"type": "signalR",
"name": "signalRMessages",
"hubName": "<hub_name>",
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
"direction": "out"
}
Este es el código de script de C#:
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
public static Task Run(
object message,
IAsyncCollector<SignalRMessage> signalRMessages)
{
return signalRMessages.AddAsync(
new SignalRMessage
{
// the message will only be sent to this user ID
UserId = "userId1",
Target = "newMessage",
Arguments = new [] { message }
});
}
Solo se pueden enviar mensajes a las conexiones que se hayan agregado a un grupo mediante el establecimiento de GroupName en el mensaje de SignalR.
Function.json de ejemplo:
{
"type": "signalR",
"name": "signalRMessages",
"hubName": "<hub_name>",
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
"direction": "out"
}
Este es el código de script de C#:
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
public static Task Run(
object message,
IAsyncCollector<SignalRMessage> signalRMessages)
{
return signalRMessages.AddAsync(
new SignalRMessage
{
// the message will be sent to the group with this name
GroupName = "myGroup",
Target = "newMessage",
Arguments = new [] { message }
});
}
SignalR Service permite que se puedan agregar usuarios o conexiones a grupos. A continuación, se pueden enviar mensajes a un grupo. Puede usar el enlace de salida SignalR
para administrar grupos.
En el ejemplo siguiente se agrega un usuario a un grupo.
function.json de ejemplo
{
"type": "signalR",
"name": "signalRGroupActions",
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
"hubName": "chat",
"direction": "out"
}
Run.csx
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
public static Task Run(
HttpRequest req,
ClaimsPrincipal claimsPrincipal,
IAsyncCollector<SignalRGroupAction> signalRGroupActions)
{
var userIdClaim = claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier);
return signalRGroupActions.AddAsync(
new SignalRGroupAction
{
UserId = userIdClaim.Value,
GroupName = "myGroup",
Action = GroupAction.Add
});
}
En el ejemplo siguiente se quita a un usuario de un grupo.
function.json de ejemplo
{
"type": "signalR",
"name": "signalRGroupActions",
"connectionStringSetting": "<name of setting containing SignalR Service connection string>",
"hubName": "chat",
"direction": "out"
}
Run.csx
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"
using Microsoft.Azure.WebJobs.Extensions.SignalRService;
public static Task Run(
HttpRequest req,
ClaimsPrincipal claimsPrincipal,
IAsyncCollector<SignalRGroupAction> signalRGroupActions)
{
var userIdClaim = claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier);
return signalRGroupActions.AddAsync(
new SignalRGroupAction
{
UserId = userIdClaim.Value,
GroupName = "myGroup",
Action = GroupAction.Remove
});
}
Salida de Twilio
En el ejemplo siguiente se muestra un enlace de salida de Twilio en un archivo function.json y una función de script de C# que usa el enlace. La función usa un parámetro out
para enviar un mensaje de texto.
Estos son los datos de enlace del archivo function.json:
Function.json de ejemplo:
{
"type": "twilioSms",
"name": "message",
"accountSidSetting": "TwilioAccountSid",
"authTokenSetting": "TwilioAuthToken",
"from": "+1425XXXXXXX",
"direction": "out",
"body": "Azure Functions Testing"
}
Este es el código de script de C#:
#r "Newtonsoft.Json"
#r "Twilio"
#r "Microsoft.Azure.WebJobs.Extensions.Twilio"
using System;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Azure.WebJobs.Extensions.Twilio;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;
public static void Run(string myQueueItem, out CreateMessageOptions message, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
// In this example the queue item is a JSON string representing an order that contains the name of a
// customer and a mobile number to send text updates to.
dynamic order = JsonConvert.DeserializeObject(myQueueItem);
string msg = "Hello " + order.name + ", thank you for your order.";
// You must initialize the CreateMessageOptions variable with the "To" phone number.
message = new CreateMessageOptions(new PhoneNumber("+1704XXXXXXX"));
// A dynamic message can be set instead of the body in the output binding. In this example, we use
// the order information to personalize a text message.
message.Body = msg;
}
No puede usar parámetros de salida en el código asincrónico. Este es un ejemplo del código de script de C# asincrónico:
#r "Newtonsoft.Json"
#r "Twilio"
#r "Microsoft.Azure.WebJobs.Extensions.Twilio"
using System;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Azure.WebJobs.Extensions.Twilio;
using Twilio.Rest.Api.V2010.Account;
using Twilio.Types;
public static async Task Run(string myQueueItem, IAsyncCollector<CreateMessageOptions> message, ILogger log)
{
log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");
// In this example the queue item is a JSON string representing an order that contains the name of a
// customer and a mobile number to send text updates to.
dynamic order = JsonConvert.DeserializeObject(myQueueItem);
string msg = "Hello " + order.name + ", thank you for your order.";
// You must initialize the CreateMessageOptions variable with the "To" phone number.
CreateMessageOptions smsText = new CreateMessageOptions(new PhoneNumber("+1704XXXXXXX"));
// A dynamic message can be set instead of the body in the output binding. In this example, we use
// the order information to personalize a text message.
smsText.Body = msg;
await message.AddAsync(smsText);
}
Desencadenador de calentamiento
En el ejemplo siguiente se muestra un desencadenador de preparación en un archivo function.json y una función de script C# que se ejecuta en cada nueva instancia cuando se agregue a la aplicación.
No compatible con la versión 1.x de Functions Runtime.
Este es el archivo function.json:
{
"bindings": [
{
"type": "warmupTrigger",
"direction": "in",
"name": "warmupContext"
}
]
}
public static void Run(WarmupContext warmupContext, ILogger log)
{
log.LogInformation("Function App instance is warm.");
}