title | description | ms.topic | ms.custom | ms.date |
---|---|---|---|---|
Azure Functions C# script developer reference | Understand how to develop Azure Functions using C# script. | conceptual | devx-track-csharp | 12/29/2024 |
This article is an introduction to developing Azure Functions by using C# script (.csx).
Important
C# script is supported primarily to provide a convenient in-portal experience to help you quickly get started creating and running C# functions. For production-quality apps, you should instead develop your C# functions locally as a compiled C# class library project. To learn how to migrate a C# script project to a C# class library (isolated worker) project, see Convert a C# script app to a C# project.
Azure Functions lets you develop functions using C# in one of the following ways:
Type | Execution process | Code extension | Development environment | Reference |
---|---|---|---|---|
C# script | in-process | .csx | Portal Core Tools | This article |
C# class library (isolated worker) | isolated worker process | .cs | Visual Studio Visual Studio Code Core Tools | .NET isolated worker process functions |
C# class library (in-process) | in-process | .cs | Visual Studio Visual Studio Code Core Tools | In-process C# class library functions |
[!INCLUDE functions-in-process-model-retirement-note]
Data flows into your C# function via method arguments. Argument names are specified in a function.json
file, and there are predefined names for accessing things like the function logger and cancellation tokens.
The .csx format allows you to write less "boilerplate" and focus on writing just a C# function. Instead of wrapping everything in a namespace and class, just define a Run
method. Include any assembly references and namespaces at the beginning of the file as usual.
A function app's .csx files are compiled when an instance is initialized. This compilation step means things like cold start may take longer for C# script functions compared to C# class libraries. This compilation step is also why C# script functions are editable in the Azure portal, while C# class libraries aren't.
The folder structure for a C# script project looks like the following example:
FunctionsProject | - MyFirstFunction | | - run.csx | | - function.json | | - function.proj | - MySecondFunction | | - run.csx | | - function.json | | - function.proj | - host.json | - extensions.csproj | - bin
There's a shared host.json file that can be used to configure the function app. Each function has its own code file (.csx) and binding configuration file (function.json).
The binding extensions required in version 2.x and later versions of the Functions runtime are defined in the extensions.csproj
file, with the actual library files in the bin
folder. When developing locally, you must register binding extensions. When you develop functions in the Azure portal, this registration is done for you.
Input or output data is bound to a C# script function parameter via the name
property in the function.json configuration file. The following example shows a function.json file and run.csx file for a queue-triggered function. The parameter that receives data from the queue message is named myQueueItem
because that's the value of the name
property.
{ "disabled": false, "bindings": [ { "type": "queueTrigger", "direction": "in", "name": "myQueueItem", "queueName": "myqueue-items", "connection":"MyStorageConnectionAppSetting" } ] }
#r "Microsoft.WindowsAzure.Storage"usingMicrosoft.Extensions.Logging;usingMicrosoft.WindowsAzure.Storage.Queue;usingSystem;publicstaticvoidRun(CloudQueueMessagemyQueueItem,ILoggerlog){log.LogInformation($"C# Queue trigger function processed: {myQueueItem.AsString}");}
The #r
statement is explained later in this article.
When possible, use managed identity-based connections in your triggers and bindings. For more information, see the Function developer guide.
Each binding has its own supported types; for instance, a blob trigger can be used with a string parameter, a POCO parameter, a CloudBlockBlob
parameter, or any of several other supported types. The binding reference article for blob bindings lists all supported parameter types for blob triggers. For more information, see Triggers and bindings and the binding reference docs for each binding type.
[!INCLUDE HTTP client best practices]
If you need to use a custom Plain Old CLR Object (POCO) class, you can include the class definition inside the same file or put it in a separate file.
The following example shows a run.csx example that includes a POCO class definition.
publicstaticvoidRun(stringmyBlob,outMyClassmyQueueItem){log.Verbose($"C# Blob trigger function processed: {myBlob}");myQueueItem=newMyClass(){Id="myid"};}publicclassMyClass{publicstringId{get;set;}}
A POCO class must have a getter and setter defined for each property.
You can use classes and methods defined in other .csx files in your run.csx file. To do that, use #load
directives in your run.csx file. In the following example, a logging routine named MyLogger
is shared in myLogger.csx and loaded into run.csx using the #load
directive:
Example run.csx:
#load "mylogger.csx"usingMicrosoft.Extensions.Logging;publicstaticvoidRun(TimerInfomyTimer,ILoggerlog){log.LogInformation($"Log by run.csx: {DateTime.Now}");MyLogger(log,$"Log by MyLogger: {DateTime.Now}");}
Example mylogger.csx:
publicstaticvoidMyLogger(ILoggerlog,stringlogtext){log.LogInformation(logtext);}
Using a shared .csx file is a common pattern when you want to strongly type the data passed between functions by using a POCO object. In the following simplified example, an HTTP trigger and queue trigger share a POCO object named Order
to strongly type the order data:
Example run.csx for HTTP trigger:
#load "..\shared\order.csx"usingSystem.Net;usingMicrosoft.Extensions.Logging;publicstaticasyncTask<HttpResponseMessage>Run(Orderreq,IAsyncCollector<Order>outputQueueItem,ILoggerlog){log.LogInformation("C# HTTP trigger function received an order.");log.LogInformation(req.ToString());log.LogInformation("Submitting to processing queue.");if(req.orderId==null){returnnewHttpResponseMessage(HttpStatusCode.BadRequest);}else{awaitoutputQueueItem.AddAsync(req);returnnewHttpResponseMessage(HttpStatusCode.OK);}}
Example run.csx for queue trigger:
#load "..\shared\order.csx"usingSystem;usingMicrosoft.Extensions.Logging;publicstaticvoidRun(OrdermyQueueItem,outOrderoutputQueueItem,ILoggerlog){log.LogInformation($"C# Queue trigger function processed order...");log.LogInformation(myQueueItem.ToString());outputQueueItem=myQueueItem;}
Example order.csx:
publicclassOrder{publicstringorderId{get;set;}publicstringcustName{get;set;}publicstringcustAddress{get;set;}publicstringcustEmail{get;set;}publicstringcartId{get;set;}publicoverrideStringToString(){return"\n{\n\torderId : "+orderId+"\n\tcustName : "+custName+"\n\tcustAddress : "+custAddress+"\n\tcustEmail : "+custEmail+"\n\tcartId : "+cartId+"\n}";}}
You can use a relative path with the #load
directive:
#load "mylogger.csx"
loads a file located in the function folder.#load "loadedfiles\mylogger.csx"
loads a file located in a folder in the function folder.#load "..\shared\mylogger.csx"
loads a file located in a folder at the same level as the function folder, that is, directly under wwwroot.
The #load
directive works only with .csx files, not with .cs files.
You can use a method return value for an output binding, by using the name $return
in function.json.
{ "name": "$return", "type": "blob", "direction": "out", "path": "output-container/{id}" }
Here's the C# script code using the return value, followed by an async example:
publicstaticstringRun(WorkIteminput,ILoggerlog){stringjson=string.Format("{{ \"id\": \"{0}\" }}",input.Id);log.LogInformation($"C# script processed queue message. Item={json}");returnjson;}
publicstaticTask<string>Run(WorkIteminput,ILoggerlog){stringjson=string.Format("{{ \"id\": \"{0}\" }}",input.Id);log.LogInformation($"C# script processed queue message. Item={json}");returnTask.FromResult(json);}
Use the return value only if a successful function execution always results in a return value to pass to the output binding. Otherwise, use ICollector
or IAsyncCollector
, as shown in the following section.
To write multiple values to an output binding, or if a successful function invocation might not result in anything to pass to the output binding, use the ICollector
or IAsyncCollector
types. These types are write-only collections that are written to the output binding when the method completes.
This example writes multiple queue messages into the same queue using ICollector
:
publicstaticvoidRun(ICollector<string>myQueue,ILoggerlog){myQueue.Add("Hello");myQueue.Add("World!");}
To log output to your streaming logs in C#, include an argument of type ILogger. We recommend that you name it log
. Avoid using Console.Write
in Azure Functions.
publicstaticvoidRun(stringmyBlob,ILoggerlog){log.LogInformation($"C# Blob trigger function processed: {myBlob}");}
Note
For information about a newer logging framework that you can use instead of TraceWriter
, see the ILogger documentation in the .NET class library developer guide.
You can use the LogMetric
extension method on ILogger
to create custom metrics in Application Insights. Here's a sample method call:
logger.LogMetric("TestMetric",1234);
This code is an alternative to calling TrackMetric
by using the Application Insights API for .NET.
To make a function asynchronous, use the async
keyword and return a Task
object.
publicasyncstaticTaskProcessQueueMessageAsync(stringblobName,StreamblobInput,StreamblobOutput){awaitblobInput.CopyToAsync(blobOutput,4096);}
You can't use out
parameters in async functions. For output bindings, use the function return value or a collector object instead.
A function can accept a CancellationToken parameter, which enables the operating system to notify your code when the function is about to be terminated. You can use this notification to make sure the function doesn't terminate unexpectedly in a way that leaves data in an inconsistent state.
The following example shows how to check for impending function termination.
usingSystem;usingSystem.IO;usingSystem.Threading;publicstaticvoidRun(stringinputText,TextWriterlogger,CancellationTokentoken){for(inti=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);}}
If you need to import namespaces, you can do so as usual, with the using
clause.
usingSystem.Net;usingSystem.Threading.Tasks;usingMicrosoft.Extensions.Logging;publicstaticTask<HttpResponseMessage>Run(HttpRequestMessagereq,ILoggerlog)
The following namespaces are automatically imported and are therefore optional:
System
System.Collections.Generic
System.IO
System.Linq
System.Net.Http
System.Threading.Tasks
Microsoft.Azure.WebJobs
Microsoft.Azure.WebJobs.Host
For framework assemblies, add references by using the #r "AssemblyName"
directive.
#r "System.Web.Http"usingSystem.Net;usingSystem.Net.Http;usingSystem.Threading.Tasks;usingMicrosoft.Extensions.Logging;publicstaticTask<HttpResponseMessage>Run(HttpRequestMessagereq,ILoggerlog)
The following assemblies are automatically added by the Azure Functions hosting environment:
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
The following assemblies may be referenced by simple-name, by runtime version:
Newtonsoft.Json
Microsoft.WindowsAzure.Storage
*
*Removed in version 4.x of the runtime.
Newtonsoft.Json
Microsoft.WindowsAzure.Storage
Microsoft.ServiceBus
Microsoft.AspNet.WebHooks.Receivers
Microsoft.AspNet.WebHooks.Common
In code, assemblies are referenced like the following example:
#r "AssemblyName"
To reference a custom assembly, you can use either a shared assembly or a private assembly:
Shared assemblies are shared across all functions within a function app. To reference a custom assembly, upload the assembly to a folder named
bin
in the root folder (wwwroot) of your function app.Private assemblies are part of a given function's context, and support side-loading of different versions. Private assemblies should be uploaded in a
bin
folder in the function directory. Reference the assemblies using the file name, such as#r "MyAssembly.dll"
.
For information on how to upload files to your function folder, see the section on package management.
The directory that contains the function script file is automatically watched for changes to assemblies. To watch for assembly changes in other directories, add them to the watchDirectories
list in host.json.
The way that both binding extension packages and other NuGet packages are added to your function app depends on the targeted version of the Functions runtime.
By default, the supported set of Functions extension NuGet packages are made available to your C# script function app by using extension bundles. To learn more, see Extension bundles.
If for some reason you can't use extension bundles in your project, you can also use the Azure Functions Core Tools to install extensions based on bindings defined in the function.json files in your app. When using Core Tools to register extensions, make sure to use the --csx
option. To learn more, see func extensions install.
By default, Core Tools reads the function.json files and adds the required packages to an extensions.csproj C# class library project file in the root of the function app's file system (wwwroot). Because Core Tools uses dotnet.exe, you can use it to add any NuGet package reference to this extensions file. During installation, Core Tools builds the extensions.csproj to install the required libraries. Here's an example extensions.csproj file that adds a reference to Microsoft.ProjectOxford.Face version 1.1.0:
<ProjectSdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReferenceInclude="Microsoft.ProjectOxford.Face"Version="1.1.0" /> </ItemGroup> </Project>
Note
For C# script (.csx), you must set TargetFramework
to a value of netstandard2.0
. Other target frameworks, such as net6.0
, aren't supported.
Version 1.x of the Functions runtime uses a project.json file to define dependencies. Here's an example project.json file:
{ "frameworks": { "net46":{ "dependencies": { "Microsoft.ProjectOxford.Face": "1.1.0" } } } }
Extension bundles aren't supported by version 1.x.
To use a custom NuGet feed, specify the feed in a Nuget.Config file in the function app root folder. For more information, see Configuring NuGet behavior.
If you're working on your project only in the portal, you'll need to manually create the extensions.csproj file or a Nuget.Config file directly in the site. To learn more, see Manually install extensions.
To get an environment variable or an app setting value, use System.Environment.GetEnvironmentVariable
, as shown in the following code example:
publicstaticvoidRun(TimerInfomyTimer,ILoggerlog){log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");log.LogInformation(GetEnvironmentVariable("AzureWebJobsStorage"));log.LogInformation(GetEnvironmentVariable("WEBSITE_SITE_NAME"));}publicstaticstringGetEnvironmentVariable(stringname){returnname+": "+System.Environment.GetEnvironmentVariable(name,EnvironmentVariableTarget.Process);}
Functions supports two built-in retry policies. For more information, see Retry policies.
Here's the retry policy in the function.json file:
{ "disabled": false, "bindings": [ { .... } ], "retry": { "strategy": "fixedDelay", "maxRetryCount": 4, "delayInterval": "00:00:10" } }
function.json property | Description |
---|---|
strategy | Use fixedDelay . |
maxRetryCount | Required. The maximum number of retries allowed per function execution. -1 means to retry indefinitely. |
delayInterval | The delay that's used between retries. Specify it as a string with the format HH:mm:ss . |
Here's the retry policy in the function.json file:
{ "disabled": false, "bindings": [ { .... } ], "retry": { "strategy": "exponentialBackoff", "maxRetryCount": 5, "minimumInterval": "00:00:10", "maximumInterval": "00:15:00" } }
function.json property | Description |
---|---|
strategy | Use exponentialBackoff . |
maxRetryCount | Required. The maximum number of retries allowed per function execution. -1 means to retry indefinitely. |
minimumInterval | The minimum retry delay. Specify it as a string with the format HH:mm:ss . |
maximumInterval | The maximum retry delay. Specify it as a string with the format HH:mm:ss . |
In C# and other .NET languages, you can use an imperative binding pattern, as opposed to the declarative bindings in function.json. Imperative binding is useful when binding parameters need to be computed at runtime rather than design time. With this pattern, you can bind to supported input and output bindings on-the-fly in your function code.
Define an imperative binding as follows:
- Do not include an entry in function.json for your desired imperative bindings.
- Pass in an input parameter
Binder binder
orIBinder binder
. - Use the following C# pattern to perform the data binding.
using(varoutput=awaitbinder.BindAsync<T>(newBindingTypeAttribute(...))){ ...}
BindingTypeAttribute
is the .NET attribute that defines your binding and T
is an input or output type that's supported by that binding type. T
can't be an out
parameter type (such as out JObject
). For example, the Mobile Apps table output binding supports six output types, but you can only use ICollector<T> or IAsyncCollector<T>
for T
.
The following example code creates a Storage blob output binding with blob path that's defined at run time, then writes a string to the blob.
usingMicrosoft.Azure.WebJobs;usingMicrosoft.Azure.WebJobs.Host.Bindings.Runtime;publicstaticasyncTaskRun(stringinput,Binderbinder){using(varwriter=awaitbinder.BindAsync<TextWriter>(newBlobAttribute("samples-output/path"))){writer.Write("Hello World!!");}}
BlobAttribute defines the Storage blob input or output binding, and TextWriter is a supported output binding type.
The preceding example gets the app setting for the function app's main Storage account connection string (which is AzureWebJobsStorage
). You can specify a custom app setting to use for the Storage account by adding the StorageAccountAttribute and passing the attribute array into BindAsync<T>()
. Use a Binder
parameter, not IBinder
. For example:
usingMicrosoft.Azure.WebJobs;usingMicrosoft.Azure.WebJobs.Host.Bindings.Runtime;publicstaticasyncTaskRun(stringinput,Binderbinder){varattributes=newAttribute[]{newBlobAttribute("samples-output/path"),newStorageAccountAttribute("MyStorageAccount")};using(varwriter=awaitbinder.BindAsync<TextWriter>(attributes)){writer.Write("Hello World!");}}
The following table lists the .NET attributes for each binding type and the packages in which they're defined.
[!div class="mx-codeBreakAll"]
The easiest way to convert a C# script function app to a compiled C# class library project is to start with a new project. You can then, for each function, migrate the code and configuration from each run.csx file and function.json file in a function folder to a single new .cs class library code file. For example, when you have a C# script function named HelloWorld
you'll have two files: HelloWorld/run.csx
and HelloWorld/function.json
. For this function, you create a code file named HelloWorld.cs
in your new class library project.
If you are using C# scripting for portal editing, you can download the app content to your local machine. Choose the Site content option instead of Content and Visual Studio project. You don't need to generate a project, and don't include application settings in the download. You're defining a new development environment, and this environment shouldn't have the same permissions as your hosted app environment.
These instructions show you how to convert C# script functions (which run in-process with the Functions host) to C# class library functions that run in an isolated worker process.
Complete the Create a functions app project section from your preferred quickstart:
Create a C# function in Azure from the command line
Create your first C# function in Azure using Visual Studio
Create your first C# function in Azure using Visual Studio Code
If your original C# script code includes an
extensions.csproj
file or anyfunction.proj
files, copy the package references from these file and add them to the new project's.csproj
file in the sameItemGroup
with the Functions core dependencies.[!TIP] Conversion provides a good opportunity to update to the latest versions of your dependencies. Doing so may require additional code changes in a later step.
Copy the contents of the original
host.json
file into the new project'shost.json
file, except for theextensionBundles
section (compiled C# projects don't use extension bundles and you must explicitly add references to all extensions used by your functions). When merging host.json files, remember that thehost.json
schema is versioned, with most apps using version 2.0. The contents of theextensions
section can differ based on specific versions of the binding extensions used by your functions. See individual extension reference articles to learn how to correctly configure the host.json for your specific versions.For any shared files referenced by a
#load
directive, create a new.cs
file for each of these shared references. It's simplest to create a new.cs
file for each shared class definition. If there are static methods without a class, you need to define new classes for these methods.Perform the following tasks for each
<FUNCTION_NAME>
folder in your original project:Create a new file named
<FUNCTION_NAME>.cs
, replacing<FUNCTION_NAME>
with the name of the folder that defined your C# script function. You can create a new function code file from one of the trigger-specific templates in the following way:Using the
func new --name <FUNCTION_NAME>
command and choosing the correct trigger template at the prompt.Following Add a function to your project in the Visual Studio guide.
Following Add a function to your project in the Visual Studio Code guide.
Copy the
using
statements from yourrun.csx
file and add them to the new file. You do not need any#r
directives.For any
#load
statement in yourrun.csx
file, add a newusing
statement for the namespace you used for the shared code.In the new file, define a class for your function under the namespace you are using for the project.
Create a new method named
RunHandler
or something similar. This new method serves as the new entry point for the function.Copy the static method that represents your function, along with any functions it calls, from
run.csx
into your new class as a second method. From the new method you created in the previous step, call into this static method. This indirection step is helpful for navigating any differences as you continue the upgrade. You can keep the original method exactly the same and simply control its inputs from the new context. You may need to create parameters on the new method which you then pass into the static method call. After you have confirmed that the migration has worked as intended, you can remove this extra level of indirection.For each binding in the
function.json
file, add the corresponding attribute to your new method. To quickly find binding examples, see Manually add bindings based on examples.Add any extension packages required by the bindings to your project, if you haven't already done so.
Recreate any application settings required by your app in the
Values
collection of the local.settings.json file.Verify that your project runs locally:
Use
func start
to run your app from the command line. For more information, see Run functions locally.Follow the Run functions locally section of the Visual Studio guide.
Follow the Run functions locally section of the Visual Studio Code guide.
Publish your project to a new function app in Azure:
Create your Azure resources and deploy the code project to Azure by using the
func azure functionapp publish <APP_NAME>
command. For more information, see Deploy project files.Follow the Publish to Azure section of the Visual Studio guide.
Follow the Create Azure resources section of the Visual Studio Code guide.
This section shows an example of the migration for a single function.
The original function in C# scripting has two files:
HelloWorld/function.json
HelloWorld/run.csx
The contents of HelloWorld/function.json
are:
{ "bindings": [ { "authLevel": "FUNCTION", "name": "req", "type": "httpTrigger", "direction": "in", "methods": [ "get", "post" ] }, { "name": "$return", "type": "http", "direction": "out" } ] }
The contents of HelloWorld/run.csx
are:
#r "Newtonsoft.Json"usingSystem.Net;usingMicrosoft.AspNetCore.Mvc;usingMicrosoft.Extensions.Primitives;usingNewtonsoft.Json;publicstaticasyncTask<IActionResult>Run(HttpRequestreq,ILoggerlog){log.LogInformation("C# HTTP trigger function processed a request.");stringname=req.Query["name"];stringrequestBody=awaitnewStreamReader(req.Body).ReadToEndAsync();dynamicdata=JsonConvert.DeserializeObject(requestBody);name=name??data?.name;stringresponseMessage=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.";returnnewOkObjectResult(responseMessage);}
After migrating to the isolated worker model with ASP.NET Core integration, these are replaced by a single HelloWorld.cs
:
usingSystem.Net;usingMicrosoft.Azure.Functions.Worker;usingMicrosoft.AspNetCore.Http;usingMicrosoft.AspNetCore.Mvc;usingMicrosoft.Extensions.Logging;usingMicrosoft.AspNetCore.Routing;usingMicrosoft.Extensions.Primitives;usingNewtonsoft.Json;namespaceMyFunctionApp{publicclassHelloWorld{privatereadonlyILogger_logger;publicHelloWorld(ILoggerFactoryloggerFactory){_logger=loggerFactory.CreateLogger<HelloWorld>();}[Function("HelloWorld")]publicasyncTask<IActionResult>RunHandler([HttpTrigger(AuthorizationLevel.Function,"get")]HttpRequestreq){returnawaitRun(req,_logger);}// From run.csxpublicstaticasyncTask<IActionResult>Run(HttpRequestreq,ILoggerlog){log.LogInformation("C# HTTP trigger function processed a request.");stringname=req.Query["name"];stringrequestBody=awaitnewStreamReader(req.Body).ReadToEndAsync();dynamicdata=JsonConvert.DeserializeObject(requestBody);name=name??data?.name;stringresponseMessage=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.";returnnewOkObjectResult(responseMessage);}}}
This section contains references and examples for defining triggers and bindings in C# script.
The following table explains the binding configuration properties for C# script that you set in the function.json file.
function.json property | Description |
---|---|
type | Must be set to blobTrigger . This property is set automatically when you create the trigger in the Azure portal. |
direction | Must be set to in . This property is set automatically when you create the trigger in the Azure portal. |
name | The name of the variable that represents the blob in function code. |
path | The container to monitor. May be a blob name pattern. |
connection | The name of an app setting or setting collection that specifies how to connect to Azure Blobs. See Connections. |
The following example shows a blob trigger definition in a function.json file and code that uses the binding. The function writes a log when a blob is added or updated in the samples-workitems
container.
Here's the binding data in the function.json file:
{ "disabled": false, "bindings": [ { "name": "myBlob", "type": "blobTrigger", "direction": "in", "path": "samples-workitems/{name}", "connection":"MyStorageAccountAppSetting" } ] }
The string {name}
in the blob trigger path samples-workitems/{name}
creates a binding expression that you can use in function code to access the file name of the triggering blob. For more information, see Blob name patterns.
Here's C# script code that binds to a Stream
:
publicstaticvoidRun(StreammyBlob,stringname,ILoggerlog){log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name}\n Size: {myBlob.Length} Bytes");}
Here's C# script code that binds to a CloudBlockBlob
:
#r "Microsoft.WindowsAzure.Storage"usingMicrosoft.WindowsAzure.Storage.Blob;publicstaticvoidRun(CloudBlockBlobmyBlob,stringname,ILoggerlog){log.LogInformation($"C# Blob trigger function Processed blob\n Name:{name}\nURI:{myBlob.StorageUri}");}
The following table explains the binding configuration properties for C# script that you set in the function.json file.
function.json property | Description |
---|---|
type | Must be set to blob . |
direction | Must be set to in . |
name | The name of the variable that represents the blob in function code. |
path | The path to the blob. |
connection | The name of an app setting or setting collection that specifies how to connect to Azure Blobs. See Connections. |
The following example shows blob input and output bindings in a function.json file and C# script code that uses the bindings. The function makes a copy of a text blob. The function is triggered by a queue message that contains the name of the blob to copy. The new blob is named {originalblobname}-Copy.
In the function.json file, the queueTrigger
metadata property is used to specify the blob name in the path
properties:
{ "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 }
Here's the C# script code:
publicstaticvoidRun(stringmyQueueItem,stringmyInputBlob,outstringmyOutputBlob,ILoggerlog){log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");myOutputBlob=myInputBlob;}
The following table explains the binding configuration properties for C# script that you set in the function.json file.
function.json property | Description |
---|---|
type | Must be set to blob . |
direction | Must be set to out . |
name | The name of the variable that represents the blob in function code. |
path | The path to the blob. |
connection | The name of an app setting or setting collection that specifies how to connect to Azure Blobs. See Connections. |
The following example shows blob input and output bindings in a function.json file and C# script code that uses the bindings. The function makes a copy of a text blob. The function is triggered by a queue message that contains the name of the blob to copy. The new blob is named {originalblobname}-Copy.
In the function.json file, the queueTrigger
metadata property is used to specify the blob name in the path
properties:
{ "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 }
Here's the C# script code:
publicstaticvoidRun(stringmyQueueItem,stringmyInputBlob,outstringmyOutputBlob,ILoggerlog){log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");myOutputBlob=myInputBlob;}
The following example shows a RabbitMQ trigger binding in a function.json file and a C# script function that uses the binding. The function reads and logs the RabbitMQ message.
Here's the binding data in the function.json file:
{"bindings": [ {"name": "myQueueItem", "type": "rabbitMQTrigger", "direction": "in", "queueName": "queue", "connectionStringSetting": "rabbitMQConnectionAppSetting" } ] }
Here's the C# script code:
usingSystem;publicstaticvoidRun(stringmyQueueItem,ILoggerlog){ log.LogInformation($"C# Script RabbitMQ trigger function processed: {myQueueItem}");}
The following table explains the binding configuration properties for C# script that you set in the function.json file.
function.json property | Description |
---|---|
type | Must be set to queueTrigger . This property is set automatically when you create the trigger in the Azure portal. |
direction | In the function.json file only. Must be set to in . This property is set automatically when you create the trigger in the Azure portal. |
name | The name of the variable that contains the queue item payload in the function code. |
queueName | The name of the queue to poll. |
connection | The name of an app setting or setting collection that specifies how to connect to Azure Queues. See Connections. |
The following example shows a queue trigger binding in a function.json file and C# script code that uses the binding. The function polls the myqueue-items
queue and writes a log each time a queue item is processed.
Here's the function.json file:
{ "disabled": false, "bindings": [ { "type": "queueTrigger", "direction": "in", "name": "myQueueItem", "queueName": "myqueue-items", "connection":"MyStorageConnectionAppSetting" } ] }
Here's the C# script code:
#r "Microsoft.WindowsAzure.Storage"usingMicrosoft.Extensions.Logging;usingMicrosoft.WindowsAzure.Storage.Queue;usingSystem;publicstaticvoidRun(CloudQueueMessagemyQueueItem,DateTimeOffsetexpirationTime,DateTimeOffsetinsertionTime,DateTimeOffsetnextVisibleTime,stringqueueTrigger,stringid,stringpopReceipt,intdequeueCount,ILoggerlog){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}");}
The following table explains the binding configuration properties for C# script that you set in the function.json file.
function.json property | Description |
---|---|
type | Must be set to queue . This property is set automatically when you create the trigger in the Azure portal. |
direction | Must be set to out . This property is set automatically when you create the trigger in the Azure portal. |
name | The name of the variable that represents the queue in function code. Set to $return to reference the function return value. |
queueName | The name of the queue. |
connection | The name of an app setting or setting collection that specifies how to connect to Azure Queues. See Connections. |
The following example shows an HTTP trigger binding in a function.json file and C# script code that uses the binding. The function creates a queue item with a CustomQueueMessage object payload for each HTTP request received.
Here's the function.json file:
{ "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" } ] }
Here's C# script code that creates a single queue message:
publicclassCustomQueueMessage{publicstringPersonName{get;set;}publicstringTitle{get;set;}}publicstaticCustomQueueMessageRun(CustomQueueMessageinput,ILoggerlog){returninput;}
You can send multiple messages at once by using an ICollector
or IAsyncCollector
parameter. Here's C# script code that sends multiple messages, one with the HTTP request data and one with hard-coded values:
publicstaticvoidRun(CustomQueueMessageinput,ICollector<CustomQueueMessage>myQueueItems,ILoggerlog){myQueueItems.Add(input);myQueueItems.Add(newCustomQueueMessage{PersonName="You",Title="None"});}
This section outlines support for the Tables API version of the extension only.
The following table explains the binding configuration properties for C# script that you set in the function.json file.
function.json property | Description |
---|---|
type | Must be set to table . This property is set automatically when you create the binding in the Azure portal. |
direction | Must be set to in . This property is set automatically when you create the binding in the Azure portal. |
name | The name of the variable that represents the table or entity in function code. |
tableName | The name of the table. |
partitionKey | Optional. The partition key of the table entity to read. |
rowKey | Optional. The row key of the table entity to read. Can't be used with take or filter . |
take | Optional. The maximum number of entities to return. Can't be used with rowKey . |
filter | Optional. An OData filter expression for the entities to return from the table. Can't be used with rowKey . |
connection | The name of an app setting or setting collection that specifies how to connect to the table service. See Connections. |
The following example shows a table input binding in a function.json file and C# script code that uses the binding. The function uses a queue trigger to read a single table row.
The function.json file specifies a partitionKey
and a rowKey
. The rowKey
value {queueTrigger}
indicates that the row key comes from the queue message string.
{ "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 }
Here's the C# script code:
#r "Azure.Data.Tables"usingMicrosoft.Extensions.Logging;usingAzure.Data.Tables;publicstaticvoidRun(stringmyQueueItem,PersonpersonEntity,ILoggerlog){log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");log.LogInformation($"Name in Person entity: {personEntity.Name}");}publicclassPerson:ITableEntity{publicstringName{get;set;}publicstringPartitionKey{get;set;}publicstringRowKey{get;set;}publicDateTimeOffset?Timestamp{get;set;}publicETagETag{get;set;}}
This section outlines support for the Tables API version of the extension only.
The following table explains the binding configuration properties for C# script that you set in the function.json file.
function.json property | Description |
---|---|
type | Must be set to table . This property is set automatically when you create the binding in the Azure portal. |
direction | Must be set to out . This property is set automatically when you create the binding in the Azure portal. |
name | The variable name used in function code that represents the table or entity. Set to $return to reference the function return value. |
tableName | The name of the table to which to write. |
partitionKey | The partition key of the table entity to write. |
rowKey | The row key of the table entity to write. |
connection | The name of an app setting or setting collection that specifies how to connect to the table service. See Connections. |
The following example shows a table output binding in a function.json file and C# script code that uses the binding. The function writes multiple table entities.
Here's the function.json file:
{ "bindings": [ { "name": "input", "type": "manualTrigger", "direction": "in" }, { "tableName": "Person", "connection": "MyStorageConnectionAppSetting", "name": "tableBinding", "type": "table", "direction": "out" } ], "disabled": false }
Here's the C# script code:
publicstaticvoidRun(stringinput,ICollector<Person>tableBinding,ILoggerlog){for(inti=1;i<10;i++){log.LogInformation($"Adding Person entity {i}");tableBinding.Add(newPerson(){PartitionKey="Test",RowKey=i.ToString(),Name="Name"+i.ToString()});}}publicclassPerson{publicstringPartitionKey{get;set;}publicstringRowKey{get;set;}publicstringName{get;set;}}
The following table explains the binding configuration properties for C# script that you set in the function.json file.
function.json property | Description |
---|---|
type | Must be set to timerTrigger . This property is set automatically when you create the trigger in the Azure portal. |
direction | Must be set to in . This property is set automatically when you create the trigger in the Azure portal. |
name | The name of the variable that represents the timer object in function code. |
schedule | A CRON expression or a TimeSpan value. A TimeSpan can be used only for a function app that runs on an App Service Plan. You can put the schedule expression in an app setting and set this property to the app setting name wrapped in % signs, as in this example: "%ScheduleAppSetting%". |
runOnStartup | If true , the function is invoked when the runtime starts. For example, the runtime starts when the function app wakes up after going idle due to inactivity. when the function app restarts due to function changes, and when the function app scales out. Use with caution.runOnStartup should rarely if ever be set to true , especially in production. |
useMonitor | Set to true or false to indicate whether the schedule should be monitored. Schedule monitoring persists schedule occurrences to aid in ensuring the schedule is maintained correctly even when function app instances restart. If not set explicitly, the default is true for schedules that have a recurrence interval greater than or equal to 1 minute. For schedules that trigger more than once per minute, the default is false . |
The following example shows a timer trigger binding in a function.json file and a C# script function that uses the binding. The function writes a log indicating whether this function invocation is due to a missed schedule occurrence. The TimerInfo
object is passed into the function.
Here's the binding data in the function.json file:
{ "schedule": "0 */5 * * * *", "name": "myTimer", "type": "timerTrigger", "direction": "in" }
Here's the C# script code:
publicstaticvoidRun(TimerInfomyTimer,ILoggerlog){if(myTimer.IsPastDue){log.LogInformation("Timer is running late!");}log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");}
The following table explains the trigger configuration properties that you set in the function.json file:
function.json property | Description |
---|---|
type | Required - must be set to httpTrigger . |
direction | Required - must be set to in . |
name | Required - the variable name used in function code for the request or request body. |
authLevel | Determines what keys, if any, need to be present on the request in order to invoke the function. For supported values, see Authorization level. |
methods | An array of the HTTP methods to which the function responds. If not specified, the function responds to all HTTP methods. See customize the HTTP endpoint. |
route | Defines the route template, controlling to which request URLs your function responds. The default value if none is provided is <functionname> . For more information, see customize the HTTP endpoint. |
webHookType | Supported only for the version 1.x runtime. Configures the HTTP trigger to act as a webhook receiver for the specified provider. For supported values, see WebHook type. |
The following example shows a trigger binding in a function.json file and a C# script function that uses the binding. The function looks for a name
parameter either in the query string or the body of the HTTP request.
Here's the function.json file:
{ "disabled": false, "bindings": [ { "authLevel": "function", "name": "req", "type": "httpTrigger", "direction": "in", "methods": [ "get", "post" ] }, { "name": "$return", "type": "http", "direction": "out" } ] }
Here's C# script code that binds to HttpRequest
:
#r "Newtonsoft.Json"usingSystem.Net;usingMicrosoft.AspNetCore.Mvc;usingMicrosoft.Extensions.Primitives;usingNewtonsoft.Json;publicstaticasyncTask<IActionResult>Run(HttpRequestreq,ILoggerlog){log.LogInformation("C# HTTP trigger function processed a request.");stringname=req.Query["name"];stringrequestBody=String.Empty;using(StreamReaderstreamReader=newStreamReader(req.Body)){requestBody=awaitstreamReader.ReadToEndAsync();}dynamicdata=JsonConvert.DeserializeObject(requestBody);name=name??data?.name;returnname!=null?(ActionResult)newOkObjectResult($"Hello, {name}"):newBadRequestObjectResult("Please pass a name on the query string or in the request body");}
You can bind to a custom object instead of HttpRequest
. This object is created from the body of the request and parsed as JSON. Similarly, a type can be passed to the HTTP response output binding and returned as the response body, along with a 200
status code.
usingSystem.Net;usingSystem.Threading.Tasks;usingMicrosoft.Extensions.Logging;publicstaticstringRun(Personperson,ILoggerlog){returnperson.Name!=null?(ActionResult)newOkObjectResult($"Hello, {person.Name}"):newBadRequestObjectResult("Please pass an instance of Person.");}publicclassPerson{publicstringName{get;set;}}
The following table explains the binding configuration properties that you set in the function.json file.
Property | Description |
---|---|
type | Must be set to http . |
direction | Must be set to out . |
name | The variable name used in function code for the response, or $return to use the return value. |
The following table explains the trigger configuration properties that you set in the function.json file:
function.json property | Description |
---|---|
type | Must be set to eventHubTrigger . This property is set automatically when you create the trigger in the Azure portal. |
direction | Must be set to in . This property is set automatically when you create the trigger in the Azure portal. |
name | The name of the variable that represents the event item in function code. |
eventHubName | Functions 2.x and higher. The name of the event hub. When the event hub name is also present in the connection string, that value overrides this property at runtime. Can be referenced via app settings%eventHubName% . In version 1.x, this property is named path . |
consumerGroup | An optional property that sets the consumer group used to subscribe to events in the hub. If omitted, the $Default consumer group is used. |
connection | The name of an app setting or setting collection that specifies how to connect to Event Hubs. See Connections. |
The following example shows an Event Hubs trigger binding in a function.json file and a C# script function that uses the binding. The function logs the message body of the Event Hubs trigger.
The following examples show Event Hubs binding data in the function.json file for Functions runtime version 2.x and later versions.
{ "type": "eventHubTrigger", "name": "myEventHubMessage", "direction": "in", "eventHubName": "MyEventHub", "connection": "myEventHubReadConnectionAppSetting" }
Here's the C# script code:
usingSystem;publicstaticvoidRun(stringmyEventHubMessage,TraceWriterlog){log.Info($"C# function triggered to process a message: {myEventHubMessage}");}
To get access to event metadata in function code, bind to an EventData object. You can also access the same properties by using binding expressions in the method signature. The following example shows both ways to get the same data:
#r "Microsoft.Azure.EventHubs"usingSystem.Text;usingSystem;usingMicrosoft.ServiceBus.Messaging;usingMicrosoft.Azure.EventHubs;publicvoidRun(EventDatamyEventHubMessage,DateTimeenqueuedTimeUtc,Int64sequenceNumber,stringoffset,TraceWriterlog){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 expressionslog.Info($"EnqueuedTimeUtc={enqueuedTimeUtc}");log.Info($"SequenceNumber={sequenceNumber}");log.Info($"Offset={offset}");}
To receive events in a batch, make string
or EventData
an array:
publicstaticvoidRun(string[]eventHubMessages,TraceWriterlog){foreach(varmessageineventHubMessages){log.Info($"C# function triggered to process a message: {message}");}}
The following table explains the binding configuration properties that you set in the function.json file.
function.json property | Description |
---|---|
type | Must be set to eventHub . |
direction | Must be set to out . This parameter is set automatically when you create the binding in the Azure portal. |
name | The variable name used in function code that represents the event. |
eventHubName | Functions 2.x and higher. The name of the event hub. When the event hub name is also present in the connection string, that value overrides this property at runtime. In Functions 1.x, this property is named path . |
connection | The name of an app setting or setting collection that specifies how to connect to Event Hubs. To learn more, see Connections. |
The following example shows an event hub trigger binding in a function.json file and a C# script function that uses the binding. The function writes a message to an event hub.
The following examples show Event Hubs binding data in the function.json file for Functions runtime version 2.x and later versions.
{ "type": "eventHub", "name": "outputEventHubMessage", "eventHubName": "myeventhub", "connection": "MyEventHubSendAppSetting", "direction": "out" }
Here's C# script code that creates one message:
usingSystem;usingMicrosoft.Extensions.Logging;publicstaticvoidRun(TimerInfomyTimer,outstringoutputEventHubMessage,ILoggerlog){Stringmsg=$"TimerTriggerCSharp1 executed at: {DateTime.Now}";log.LogInformation(msg);outputEventHubMessage=msg;}
Here's C# script code that creates multiple messages:
publicstaticvoidRun(TimerInfomyTimer,ICollector<string>outputEventHubMessage,ILoggerlog){stringmessage=$"Message created at: {DateTime.Now}";log.LogInformation(message);outputEventHubMessage.Add("1 "+message);outputEventHubMessage.Add("2 "+message);}
The following table explains the binding configuration properties for C# script that you set in the function.json file. There are no constructor parameters or properties to set in the EventGridTrigger
attribute.
function.json property | Description |
---|---|
type | Required - must be set to eventGridTrigger . |
direction | Required - must be set to in . |
name | Required - the variable name used in function code for the parameter that receives the event data. |
The following example shows an Event Grid trigger defined in the function.json file.
Here's the binding data in the function.json file:
{ "bindings": [ { "type": "eventGridTrigger", "name": "eventGridEvent", "direction": "in" } ], "disabled": false }
Here's an example of a C# script function that uses an EventGridEvent
binding parameter:
#r "Azure.Messaging.EventGrid"usingAzure.Messaging.EventGrid;usingMicrosoft.Extensions.Logging;publicstaticvoidRun(EventGridEventeventGridEvent,ILoggerlog){log.LogInformation(eventGridEvent.Data.ToString());}
Here's an example of a C# script function that uses a JObject
binding parameter:
#r "Newtonsoft.Json"usingNewtonsoft.Json;usingNewtonsoft.Json.Linq;publicstaticvoidRun(JObjecteventGridEvent,TraceWriterlog){log.Info(eventGridEvent.ToString(Formatting.Indented));}
The following table explains the binding configuration properties for C# script that you set in the function.json file.
|function.json property | Description| |---------|---------|----------------------| |type | Must be set to eventGrid
. | |direction | Must be set to out
. This parameter is set automatically when you create the binding in the Azure portal. | |name | The variable name used in function code that represents the event. | |topicEndpointUri | The name of an app setting that contains the URI for the custom topic, such as MyTopicEndpointUri
. | |topicKeySetting | The name of an app setting that contains an access key for the custom topic. |
The following example shows the Event Grid output binding data in the function.json file.
{ "type": "eventGrid", "name": "outputEvent", "topicEndpointUri": "MyEventGridTopicUriSetting", "topicKeySetting": "MyEventGridTopicKeySetting", "direction": "out" }
Here's C# script code that creates one event:
#r "Microsoft.Azure.EventGrid"usingSystem;usingMicrosoft.Azure.EventGrid.Models;usingMicrosoft.Extensions.Logging;publicstaticvoidRun(TimerInfomyTimer,outEventGridEventoutputEvent,ILoggerlog){outputEvent=newEventGridEvent("message-id","subject-name","event-data","event-type",DateTime.UtcNow,"1.0");}
Here's C# script code that creates multiple events:
#r "Microsoft.Azure.EventGrid"usingSystem;usingMicrosoft.Azure.EventGrid.Models;usingMicrosoft.Extensions.Logging;publicstaticvoidRun(TimerInfomyTimer,ICollector<EventGridEvent>outputEvent,ILoggerlog){outputEvent.Add(newEventGridEvent("message-id-1","subject-name","event-data","event-type",DateTime.UtcNow,"1.0"));outputEvent.Add(newEventGridEvent("message-id-2","subject-name","event-data","event-type",DateTime.UtcNow,"1.0"));}
The following table explains the binding configuration properties that you set in the function.json file.
function.json property | Description |
---|---|
type | Must be set to serviceBusTrigger . This property is set automatically when you create the trigger in the Azure portal. |
direction | Must be set to in . This property is set automatically when you create the trigger in the Azure portal. |
name | The name of the variable that represents the queue or topic message in function code. |
queueName | Name of the queue to monitor. Set only if monitoring a queue, not for a topic. |
topicName | Name of the topic to monitor. Set only if monitoring a topic, not for a queue. |
subscriptionName | Name of the subscription to monitor. Set only if monitoring a topic, not for a queue. |
connection | The name of an app setting or setting collection that specifies how to connect to Service Bus. See Connections. |
accessRights | Access rights for the connection string. Available values are manage and listen . The default is manage , which indicates that the connection has the Manage permission. If you use a connection string that does not have the Manage permission, set accessRights to "listen". Otherwise, the Functions runtime might fail trying to do operations that require manage rights. In Azure Functions version 2.x and higher, this property is not available because the latest version of the Service Bus SDK doesn't support manage operations. |
isSessionsEnabled | true if connecting to a session-aware queue or subscription. false otherwise, which is the default value. |
autoComplete | true when the trigger should automatically call complete after processing, or if the function code will manually call complete.Setting to false is only supported in C#.If set to true , the trigger completes the message automatically if the function execution completes successfully, and abandons the message otherwise.<br/When set to false , you are responsible for calling ServiceBusReceiver methods to complete, abandon, or deadletter the message, session, or batch. When an exception is thrown (and none of the ServiceBusReceiver methods are called), then the lock remains. Once the lock expires, the message is re-queued with the DeliveryCount incremented and the lock is automatically renewed.This property is available only in Azure Functions 2.x and higher. |
The following example shows a Service Bus trigger binding in a function.json file and a C# script function that uses the binding. The function reads message metadata and logs a Service Bus queue message.
Here's the binding data in the function.json file:
{ "bindings": [ { "queueName": "testqueue", "connection": "MyServiceBusConnection", "name": "myQueueItem", "type": "serviceBusTrigger", "direction": "in" } ], "disabled": false }
Here's the C# script code:
usingSystem;publicstaticvoidRun(stringmyQueueItem,Int32deliveryCount,DateTimeenqueuedTimeUtc,stringmessageId,TraceWriterlog){log.Info($"C# ServiceBus queue trigger function processed message: {myQueueItem}");log.Info($"EnqueuedTimeUtc={enqueuedTimeUtc}");log.Info($"DeliveryCount={deliveryCount}");log.Info($"MessageId={messageId}");}
The following table explains the binding configuration properties that you set in the function.json file.
|function.json property | Description| |---------|---------|----------------------| |type |Must be set to serviceBus
. This property is set automatically when you create the trigger in the Azure portal.| |direction | Must be set to out
. This property is set automatically when you create the trigger in the Azure portal. | |name | The name of the variable that represents the queue or topic message in function code. Set to "$return" to reference the function return value. | |queueName|Name of the queue. Set only if sending queue messages, not for a topic. |topicName|Name of the topic. Set only if sending topic messages, not for a queue.| |connection|The name of an app setting or setting collection that specifies how to connect to Service Bus. See Connections.| |accessRights (v1 only)|Access rights for the connection string. Available values are manage
and listen
. The default is manage
, which indicates that the connection
has the Manage permission. If you use a connection string that does not have the Manage permission, set accessRights
to "listen". Otherwise, the Functions runtime might fail trying to do operations that require manage rights. In Azure Functions version 2.x and higher, this property is not available because the latest version of the Service Bus SDK doesn't support manage operations.|
The following example shows a Service Bus output binding in a function.json file and a C# script function that uses the binding. The function uses a timer trigger to send a queue message every 15 seconds.
Here's the binding data in the function.json file:
{ "bindings": [ { "schedule": "0/15 * * * * *", "name": "myTimer", "runsOnStartup": true, "type": "timerTrigger", "direction": "in" }, { "name": "outputSbQueue", "type": "serviceBus", "queueName": "testqueue", "connection": "MyServiceBusConnection", "direction": "out" } ], "disabled": false }
Here's C# script code that creates a single message:
publicstaticvoidRun(TimerInfomyTimer,ILoggerlog,outstringoutputSbQueue){stringmessage=$"Service Bus queue message created at: {DateTime.Now}";log.LogInformation(message);outputSbQueue=message;}
Here's C# script code that creates multiple messages:
publicstaticasyncTaskRun(TimerInfomyTimer,ILoggerlog,IAsyncCollector<string>outputSbQueue){stringmessage=$"Service Bus queue messages created at: {DateTime.Now}";log.LogInformation(message);awaitoutputSbQueue.AddAsync("1 "+message);awaitoutputSbQueue.AddAsync("2 "+message);}
This section outlines support for the version 4.x+ of the extension only.
The following table explains the binding configuration properties that you set in the function.json file.
[!INCLUDE functions-cosmosdb-settings-v4]
The following example shows an Azure Cosmos DB trigger binding in a function.json file and a C# script function that uses the binding. The function writes log messages when Azure Cosmos DB records are added or modified.
Here's the binding data in the function.json file:
{ "type": "cosmosDBTrigger", "name": "documents", "direction": "in", "leaseContainerName": "leases", "connection": "<connection-app-setting>", "databaseName": "Tasks", "containerName": "Items", "createLeaseContainerIfNotExists": true }
Here's the C# script code:
usingSystem;usingSystem.Collections.Generic;usingMicrosoft.Extensions.Logging;// Customize the model with your own desired propertiespublicclassToDoItem{publicstringid{get;set;}publicstringDescription{get;set;}}publicstaticvoidRun(IReadOnlyList<ToDoItem>documents,ILoggerlog){log.LogInformation("Documents modified "+documents.Count);log.LogInformation("First document Id "+documents[0].id);}
This section outlines support for the version 4.x+ of the extension only.
The following table explains the binding configuration properties that you set in the function.json file.
[!INCLUDE functions-cosmosdb-input-settings-v4]
This section contains the following examples:
- Queue trigger, look up ID from string
- Queue trigger, get multiple docs, using SqlQuery
- HTTP trigger, look up ID from query string
- HTTP trigger, look up ID from route data
- HTTP trigger, get multiple docs, using SqlQuery
- HTTP trigger, get multiple docs, using DocumentClient
The HTTP trigger examples refer to a simple ToDoItem
type:
namespaceCosmosDBSamplesV2{publicclassToDoItem{publicstringId{get;set;}publicstringDescription{get;set;}}}
The following example shows an Azure Cosmos DB input binding in a function.json file and a C# script function that uses the binding. The function reads a single document and updates the document's text value.
Here's the binding data in the function.json file:
{ "name": "inputDocument", "type": "cosmosDB", "databaseName": "MyDatabase", "collectionName": "MyCollection", "id" : "{queueTrigger}", "partitionKey": "{partition key value}", "connectionStringSetting": "MyAccount_COSMOSDB", "direction": "in" }
Here's the C# script code:
usingSystem;// Change input document contents using Azure Cosmos DB input bindingpublicstaticvoidRun(stringmyQueueItem,dynamicinputDocument){inputDocument.text="This has changed.";}
The following example shows an Azure Cosmos DB input binding in a function.json file and a C# script function that uses the binding. The function retrieves multiple documents specified by a SQL query, using a queue trigger to customize the query parameters.
The queue trigger provides a parameter departmentId
. A queue message of { "departmentId" : "Finance" }
would return all records for the finance department.
Here's the binding data in the function.json file:
{ "name": "documents", "type": "cosmosDB", "direction": "in", "databaseName": "MyDb", "collectionName": "MyCollection", "sqlQuery": "SELECT * from c where c.departmentId = {departmentId}", "connectionStringSetting": "CosmosDBConnection" }
Here's the C# script code:
publicstaticvoidRun(QueuePayloadmyQueueItem,IEnumerable<dynamic>documents){foreach(vardocindocuments){// operate on each document}}publicclassQueuePayload{publicstringdepartmentId{get;set;}}
The following example shows a C# script function that retrieves a single document. The function is triggered by an HTTP request that uses a query string to specify the ID and partition key value to look up. That ID and partition key value are used to retrieve a ToDoItem
document from the specified database and collection.
Here's the function.json file:
{ "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 }
Here's the C# script code:
usingSystem.Net;usingMicrosoft.Extensions.Logging;publicstaticHttpResponseMessageRun(HttpRequestMessagereq,ToDoItemtoDoItem,ILoggerlog){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}");}returnreq.CreateResponse(HttpStatusCode.OK);}
The following example shows a C# script function that retrieves a single document. The function is triggered by an HTTP request that uses route data to specify the ID and partition key value to look up. That ID and partition key value are used to retrieve a ToDoItem
document from the specified database and collection.
Here's the function.json file:
{ "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 }
Here's the C# script code:
usingSystem.Net;usingMicrosoft.Extensions.Logging;publicstaticHttpResponseMessageRun(HttpRequestMessagereq,ToDoItemtoDoItem,ILoggerlog){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}");}returnreq.CreateResponse(HttpStatusCode.OK);}
The following example shows a C# script function that retrieves a list of documents. The function is triggered by an HTTP request. The query is specified in the SqlQuery
attribute property.
Here's the function.json file:
{ "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 }
Here's the C# script code:
usingSystem.Net;usingMicrosoft.Extensions.Logging;publicstaticHttpResponseMessageRun(HttpRequestMessagereq,IEnumerable<ToDoItem>toDoItems,ILoggerlog){log.LogInformation("C# HTTP trigger function processed a request.");foreach(ToDoItemtoDoItemintoDoItems){log.LogInformation(toDoItem.Description);}returnreq.CreateResponse(HttpStatusCode.OK);}
The following example shows a C# script function that retrieves a list of documents. The function is triggered by an HTTP request. The code uses a DocumentClient
instance provided by the Azure Cosmos DB binding to read a list of documents. The DocumentClient
instance could also be used for write operations.
Here's the function.json file:
{ "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 }
Here's the C# script code:
#r "Microsoft.Azure.Documents.Client"usingSystem.Net;usingMicrosoft.Azure.Documents.Client;usingMicrosoft.Azure.Documents.Linq;usingMicrosoft.Extensions.Logging;publicstaticasyncTask<HttpResponseMessage>Run(HttpRequestMessagereq,DocumentClientclient,ILoggerlog){log.LogInformation("C# HTTP trigger function processed a request.");UricollectionUri=UriFactory.CreateDocumentCollectionUri("ToDoItems","Items");stringsearchterm=req.GetQueryNameValuePairs().FirstOrDefault(q =>string.Compare(q.Key,"searchterm",true)==0).Value;if(searchterm==null){returnreq.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(ToDoItemresultinawaitquery.ExecuteNextAsync()){log.LogInformation(result.Description);}}returnreq.CreateResponse(HttpStatusCode.OK);}
This section outlines support for the version 4.x+ of the extension only.
The following table explains the binding configuration properties that you set in the function.json file.
[!INCLUDE functions-cosmosdb-output-settings-v4]
This section contains the following examples:
The following example shows an Azure Cosmos DB output binding in a function.json file and a C# script function that uses the binding. The function uses a queue input binding for a queue that receives JSON in the following format:
{ "name": "John Henry", "employeeId": "123456", "address": "A town nearby" }
The function creates Azure Cosmos DB documents in the following format for each record:
{ "id": "John Henry-123456", "name": "John Henry", "employeeId": "123456", "address": "A town nearby" }
Here's the binding data in the function.json file:
{ "name": "employeeDocument", "type": "cosmosDB", "databaseName": "MyDatabase", "collectionName": "MyCollection", "createIfNotExists": true, "connectionStringSetting": "MyAccount_COSMOSDB", "direction": "out" }
Here's the C# script code:
#r "Newtonsoft.Json"usingMicrosoft.Azure.WebJobs.Host;usingNewtonsoft.Json.Linq;usingMicrosoft.Extensions.Logging;publicstaticvoidRun(stringmyQueueItem,outobjectemployeeDocument,ILoggerlog){log.LogInformation($"C# Queue trigger function processed: {myQueueItem}");dynamicemployee=JObject.Parse(myQueueItem);employeeDocument=new{id=employee.name+"-"+employee.employeeId,name=employee.name,employeeId=employee.employeeId,address=employee.address};}
To create multiple documents, you can bind to ICollector<T>
or IAsyncCollector<T>
where T
is one of the supported types.
This example refers to a simple ToDoItem
type:
namespaceCosmosDBSamplesV2{publicclassToDoItem{publicstringid{get;set;}publicstringDescription{get;set;}}}
Here's the function.json file:
{ "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 }
Here's the C# script code:
usingSystem;usingMicrosoft.Extensions.Logging;publicstaticasyncTaskRun(ToDoItem[]toDoItemsIn,IAsyncCollector<ToDoItem>toDoItemsOut,ILoggerlog){log.LogInformation($"C# Queue trigger function processed {toDoItemsIn?.Length} items");foreach(ToDoItemtoDoItemintoDoItemsIn){log.LogInformation($"Description={toDoItem.Description}");awaittoDoItemsOut.AddAsync(toDoItem);}}
The following example shows an Azure Cosmos DB trigger binding in a function.json file and a C# script function that uses the binding. The function writes log messages when Azure Cosmos DB records are modified.
Here's the binding data in the function.json file:
{ "type": "cosmosDBTrigger", "name": "documents", "direction": "in", "leaseCollectionName": "leases", "connectionStringSetting": "<connection-app-setting>", "databaseName": "Tasks", "collectionName": "Items", "createLeaseCollectionIfNotExists": true }
Here's the C# script code:
#r "Microsoft.Azure.Documents.Client"usingSystem;usingMicrosoft.Azure.Documents;usingSystem.Collections.Generic;publicstaticvoidRun(IReadOnlyList<Document>documents,TraceWriterlog){log.Info("Documents modified "+documents.Count);log.Info("First document Id "+documents[0].Id);}
This section contains the following examples:
- Queue trigger, look up ID from string
- Queue trigger, get multiple docs, using SqlQuery
- HTTP trigger, look up ID from query string
- HTTP trigger, look up ID from route data
- HTTP trigger, get multiple docs, using SqlQuery
- HTTP trigger, get multiple docs, using DocumentClient
The HTTP trigger examples refer to a simple ToDoItem
type:
namespaceCosmosDBSamplesV1{publicclassToDoItem{publicstringId{get;set;}publicstringDescription{get;set;}}}
The following example shows an Azure Cosmos DB input binding in a function.json file and a C# script function that uses the binding. The function reads a single document and updates the document's text value.
Here's the binding data in the function.json file:
{ "name": "inputDocument", "type": "documentDB", "databaseName": "MyDatabase", "collectionName": "MyCollection", "id" : "{queueTrigger}", "partitionKey": "{partition key value}", "connection": "MyAccount_COSMOSDB", "direction": "in" }
Here's the C# script code:
usingSystem;// Change input document contents using Azure Cosmos DB input bindingpublicstaticvoidRun(stringmyQueueItem,dynamicinputDocument){inputDocument.text="This has changed.";}
The following example shows an Azure Cosmos DB input binding in a function.json file and a C# script function that uses the binding. The function retrieves multiple documents specified by a SQL query, using a queue trigger to customize the query parameters.
The queue trigger provides a parameter departmentId
. A queue message of { "departmentId" : "Finance" }
would return all records for the finance department.
Here's the binding data in the function.json file:
{ "name": "documents", "type": "documentdb", "direction": "in", "databaseName": "MyDb", "collectionName": "MyCollection", "sqlQuery": "SELECT * from c where c.departmentId = {departmentId}", "connection": "CosmosDBConnection" }
Here's the C# script code:
publicstaticvoidRun(QueuePayloadmyQueueItem,IEnumerable<dynamic>documents){foreach(vardocindocuments){// operate on each document}}publicclassQueuePayload{publicstringdepartmentId{get;set;}}
The following example shows a C# script function that retrieves a single document. The function is triggered by an HTTP request that uses a query string to specify the ID to look up. That ID is used to retrieve a ToDoItem
document from the specified database and collection.
Here's the function.json file:
{ "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 }
Here's the C# script code:
usingSystem.Net;publicstaticHttpResponseMessageRun(HttpRequestMessagereq,ToDoItemtoDoItem,TraceWriterlog){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}");}returnreq.CreateResponse(HttpStatusCode.OK);}
The following example shows a C# script function that retrieves a single document. The function is triggered by an HTTP request that uses route data to specify the ID to look up. That ID is used to retrieve a ToDoItem
document from the specified database and collection.
Here's the function.json file:
{ "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 }
Here's the C# script code:
usingSystem.Net;publicstaticHttpResponseMessageRun(HttpRequestMessagereq,ToDoItemtoDoItem,TraceWriterlog){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}");}returnreq.CreateResponse(HttpStatusCode.OK);}
The following example shows a C# script function that retrieves a list of documents. The function is triggered by an HTTP request. The query is specified in the SqlQuery
attribute property.
Here's the function.json file:
{ "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 }
Here's the C# script code:
usingSystem.Net;publicstaticHttpResponseMessageRun(HttpRequestMessagereq,IEnumerable<ToDoItem>toDoItems,TraceWriterlog){log.Info("C# HTTP trigger function processed a request.");foreach(ToDoItemtoDoItemintoDoItems){log.Info(toDoItem.Description);}returnreq.CreateResponse(HttpStatusCode.OK);}
The following example shows a C# script function that retrieves a list of documents. The function is triggered by an HTTP request. The code uses a DocumentClient
instance provided by the Azure Cosmos DB binding to read a list of documents. The DocumentClient
instance could also be used for write operations.
Here's the function.json file:
{ "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 }
Here's the C# script code:
#r "Microsoft.Azure.Documents.Client"usingSystem.Net;usingMicrosoft.Azure.Documents.Client;usingMicrosoft.Azure.Documents.Linq;publicstaticasyncTask<HttpResponseMessage>Run(HttpRequestMessagereq,DocumentClientclient,TraceWriterlog){log.Info("C# HTTP trigger function processed a request.");UricollectionUri=UriFactory.CreateDocumentCollectionUri("ToDoItems","Items");stringsearchterm=req.GetQueryNameValuePairs().FirstOrDefault(q =>string.Compare(q.Key,"searchterm",true)==0).Value;if(searchterm==null){returnreq.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(ToDoItemresultinawaitquery.ExecuteNextAsync()){log.Info(result.Description);}}returnreq.CreateResponse(HttpStatusCode.OK);}
This section contains the following examples:
- Queue trigger, write one doc
- Queue trigger, write docs using
IAsyncCollector
The following example shows an Azure Cosmos DB output binding in a function.json file and a C# script function that uses the binding. The function uses a queue input binding for a queue that receives JSON in the following format:
{ "name": "John Henry", "employeeId": "123456", "address": "A town nearby" }
The function creates Azure Cosmos DB documents in the following format for each record:
{ "id": "John Henry-123456", "name": "John Henry", "employeeId": "123456", "address": "A town nearby" }
Here's the binding data in the function.json file:
{ "name": "employeeDocument", "type": "documentDB", "databaseName": "MyDatabase", "collectionName": "MyCollection", "createIfNotExists": true, "connection": "MyAccount_COSMOSDB", "direction": "out" }
Here's the C# script code:
#r "Newtonsoft.Json"usingMicrosoft.Azure.WebJobs.Host;usingNewtonsoft.Json.Linq;publicstaticvoidRun(stringmyQueueItem,outobjectemployeeDocument,TraceWriterlog){log.Info($"C# Queue trigger function processed: {myQueueItem}");dynamicemployee=JObject.Parse(myQueueItem);employeeDocument=new{id=employee.name+"-"+employee.employeeId,name=employee.name,employeeId=employee.employeeId,address=employee.address};}
To create multiple documents, you can bind to ICollector<T>
or IAsyncCollector<T>
where T
is one of the supported types.
This example refers to a simple ToDoItem
type:
namespaceCosmosDBSamplesV1{publicclassToDoItem{publicstringId{get;set;}publicstringDescription{get;set;}}}
Here's the function.json file:
{ "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 }
Here's the C# script code:
usingSystem;publicstaticasyncTaskRun(ToDoItem[]toDoItemsIn,IAsyncCollector<ToDoItem>toDoItemsOut,TraceWriterlog){log.Info($"C# Queue trigger function processed {toDoItemsIn?.Length} items");foreach(ToDoItemtoDoItemintoDoItemsIn){log.Info($"Description={toDoItem.Description}");awaittoDoItemsOut.AddAsync(toDoItem);}}
More samples for the Azure SQL trigger are available in the GitHub repository.
The example refers to a ToDoItem
class and a corresponding database table:
:::code language="csharp" source="~/functions-sql-todo-sample/ToDoModel.cs" range="6-16":::
:::code language="sql" source="~/functions-sql-todo-sample/sql/create.sql" range="1-7":::
Change tracking is enabled on the database and on the table:
ALTERDATABASE [SampleDatabase] SET CHANGE_TRACKING =ON (CHANGE_RETENTION =2 DAYS, AUTO_CLEANUP =ON); ALTERTABLE [dbo].[ToDo] ENABLE CHANGE_TRACKING;
The SQL trigger binds to a IReadOnlyList<SqlChange<T>>
, a list of SqlChange
objects each with two properties:
- Item: the item that was changed. The type of the item should follow the table schema as seen in the
ToDoItem
class. - Operation: a value from
SqlChangeOperation
enum. The possible values areInsert
,Update
, andDelete
.
The following example shows a SQL trigger in a function.json file and a C# script function that is invoked when there are changes to the ToDo
table:
The following is binding data in the function.json file:
{ "name": "todoChanges", "type": "sqlTrigger", "direction": "in", "tableName": "dbo.ToDo", "connectionStringSetting": "SqlConnectionString" }
The following is the C# script function:
#r "Newtonsoft.Json"usingSystem.Net;usingMicrosoft.AspNetCore.Mvc;usingMicrosoft.Extensions.Primitives;usingNewtonsoft.Json;publicstaticvoidRun(IReadOnlyList<SqlChange<ToDoItem>>todoChanges,ILoggerlog){log.LogInformation($"C# SQL trigger function processed a request.");foreach(SqlChange<ToDoItem>changeintodoChanges){ToDoItemtoDoItem=change.Item;log.LogInformation($"Change operation: {change.Operation}");log.LogInformation($"Id: {toDoItem.Id}, Title: {toDoItem.title}, Url: {toDoItem.url}, Completed: {toDoItem.completed}");}}
More samples for the Azure SQL input binding are available in the GitHub repository.
This section contains the following examples:
The examples refer to a ToDoItem
class and a corresponding database table:
:::code language="csharp" source="~/functions-sql-todo-sample/ToDoModel.cs" range="6-16":::
:::code language="sql" source="~/functions-sql-todo-sample/sql/create.sql" range="1-7":::
The following example shows an Azure SQL input binding in a function.json file and a C# script function that uses the binding. The function is triggered by an HTTP request that uses a query string to specify the ID. That ID is used to retrieve a ToDoItem
record with the specified query.
Note
The HTTP query string parameter is case-sensitive.
Here's the binding data in the function.json file:
{ "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" }
Here's the C# script code:
#r "Newtonsoft.Json"usingSystem.Net;usingMicrosoft.AspNetCore.Mvc;usingMicrosoft.Extensions.Primitives;usingNewtonsoft.Json;usingSystem.Collections.Generic;publicstaticIActionResultRun(HttpRequestreq,ILoggerlog,IEnumerable<ToDoItem>todoItem){returnnewOkObjectResult(todoItem);}
The following example shows an Azure SQL input binding in a function.json file and a C# script function that uses the binding to execute a stored procedure with input from the HTTP request query parameter. In this example, the stored procedure deletes a single record or all records depending on the value of the parameter.
The stored procedure dbo.DeleteToDo
must be created on the SQL database.
:::code language="sql" source="~/functions-sql-todo-sample/sql/create.sql" range="11-25":::
Here's the binding data in the function.json file:
{ "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" }
:::code language="csharp" source="~/functions-sql-todo-sample/DeleteToDo.cs" range="4-30":::
Here's the C# script code:
#r "Newtonsoft.Json"usingSystem.Net;usingMicrosoft.AspNetCore.Mvc;usingMicrosoft.Extensions.Primitives;usingNewtonsoft.Json;usingSystem.Collections.Generic;publicstaticIActionResultRun(HttpRequestreq,ILoggerlog,IEnumerable<ToDoItem>todoItems){returnnewOkObjectResult(todoItems);}
More samples for the Azure SQL output binding are available in the GitHub repository.
This section contains the following examples:
The examples refer to a ToDoItem
class and a corresponding database table:
:::code language="csharp" source="~/functions-sql-todo-sample/ToDoModel.cs" range="6-16":::
:::code language="sql" source="~/functions-sql-todo-sample/sql/create.sql" range="1-7":::
The following example shows a SQL output binding in a function.json file and a C# script function that adds records to a table, using data provided in an HTTP POST request as a JSON body.
The following is binding data in the function.json file:
{ "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" }
The following is sample C# script code:
#r "Newtonsoft.Json"usingSystem.Net;usingMicrosoft.AspNetCore.Mvc;usingMicrosoft.Extensions.Primitives;usingNewtonsoft.Json;publicstaticIActionResultRun(HttpRequestreq,ILoggerlog,outToDoItemtodoItem){log.LogInformation("C# HTTP trigger function processed a request.");stringrequestBody=newStreamReader(req.Body).ReadToEnd();todoItem=JsonConvert.DeserializeObject<ToDoItem>(requestBody);returnnewOkObjectResult(todoItem);}
The following example shows a SQL output binding in a function.json file and a C# script function that adds records to a database in two different tables (dbo.ToDo
and dbo.RequestLog
), using data provided in an HTTP POST request as a JSON body and multiple output bindings.
The second table, dbo.RequestLog
, corresponds to the following definition:
CREATETABLEdbo.RequestLog ( Id int identity(1,1) primary key, RequestTimeStamp datetime2 not null, ItemCount intnot null )
The following is binding data in the function.json file:
{ "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" }
The following is sample C# script code:
#r "Newtonsoft.Json"usingSystem.Net;usingMicrosoft.AspNetCore.Mvc;usingMicrosoft.Extensions.Primitives;usingNewtonsoft.Json;publicstaticIActionResultRun(HttpRequestreq,ILoggerlog,outToDoItemtodoItem,outRequestLogrequestLog){log.LogInformation("C# HTTP trigger function processed a request.");stringrequestBody=newStreamReader(req.Body).ReadToEnd();todoItem=JsonConvert.DeserializeObject<ToDoItem>(requestBody);requestLog=newRequestLog();requestLog.RequestTimeStamp=DateTime.Now;requestLog.ItemCount=1;returnnewOkObjectResult(todoItem);}publicclassRequestLog{publicDateTimeRequestTimeStamp{get;set;}publicintItemCount{get;set;}}
The following example shows a RabbitMQ output binding in a function.json file and a C# script function that uses the binding. The function reads in the message from an HTTP trigger and outputs it to the RabbitMQ queue.
Here's the binding data in the function.json file:
{ "bindings": [ { "type": "httpTrigger", "direction": "in", "authLevel": "function", "name": "input", "methods": [ "get", "post" ] }, { "type": "rabbitMQ", "name": "outputMessage", "queueName": "outputQueue", "connectionStringSetting": "rabbitMQConnectionAppSetting", "direction": "out" } ] }
Here's the C# script code:
usingSystem;usingMicrosoft.Extensions.Logging;publicstaticvoidRun(stringinput,outstringoutputMessage,ILoggerlog){log.LogInformation(input);outputMessage=input;}
The following example shows a SendGrid output binding in a function.json file and a C# script function that uses the binding.
Here's the binding data in the function.json file:
{ "bindings": [ { "type": "queueTrigger", "name": "mymsg", "queueName": "myqueue", "connection": "AzureWebJobsStorage", "direction": "in" }, { "type": "sendGrid", "name": "$return", "direction": "out", "apiKey": "SendGridAPIKeyAsAppSetting", "from": "{FromEmail}", "to": "{ToEmail}" } ] }
Here's the C# script code:
#r "SendGrid"usingSystem;usingSendGrid.Helpers.Mail;usingMicrosoft.Azure.WebJobs.Host;publicstaticSendGridMessageRun(Messagemymsg,ILoggerlog){SendGridMessagemessage=newSendGridMessage(){Subject=$"{mymsg.Subject}"};message.AddContent("text/plain",$"{mymsg.Content}");returnmessage;}publicclassMessage{publicstringToEmail{get;set;}publicstringFromEmail{get;set;}publicstringSubject{get;set;}publicstringContent{get;set;}}
Here's example binding data in the function.json file:
{ "type": "signalRTrigger", "name": "invocation", "hubName": "SignalRTest", "category": "messages", "event": "SendMessage", "parameterNames": [ "message" ], "direction": "in" }
And, here's the code:
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"usingSystem;usingMicrosoft.Azure.WebJobs.Extensions.SignalRService;usingMicrosoft.Extensions.Logging;publicstaticvoidRun(InvocationContextinvocation,stringmessage,ILoggerlogger){logger.LogInformation($"Receive {message} from {invocationContext.ConnectionId}.");}
The following example shows a SignalR connection info input binding in a function.json file and a C# Script function that uses the binding to return the connection information.
Here's binding data in the function.json file:
Example function.json:
{ "type": "signalRConnectionInfo", "name": "connectionInfo", "hubName": "chat", "connectionStringSetting": "<name of setting containing SignalR Service connection string>", "direction": "in" }
Here's the C# Script code:
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"usingMicrosoft.Azure.WebJobs.Extensions.SignalRService;publicstaticSignalRConnectionInfoRun(HttpRequestreq,SignalRConnectionInfoconnectionInfo){returnconnectionInfo;}
You can set the userId
property of the binding to the value from either header using a binding expression: {headers.x-ms-client-principal-id}
or {headers.x-ms-client-principal-name}
.
Example function.json:
{ "type": "signalRConnectionInfo", "name": "connectionInfo", "hubName": "chat", "userId": "{headers.x-ms-client-principal-id}", "connectionStringSetting": "<name of setting containing SignalR Service connection string>", "direction": "in" }
Here's the C# Script code:
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"usingMicrosoft.Azure.WebJobs.Extensions.SignalRService;publicstaticSignalRConnectionInfoRun(HttpRequestreq,SignalRConnectionInfoconnectionInfo){// connectionInfo contains an access key token with a name identifier// claim set to the authenticated userreturnconnectionInfo;}
Here's binding data in the function.json file:
Example function.json:
{ "type": "signalR", "name": "signalRMessages", "hubName": "<hub_name>", "connectionStringSetting": "<name of setting containing SignalR Service connection string>", "direction": "out" }
Here's the C# Script code:
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"usingMicrosoft.Azure.WebJobs.Extensions.SignalRService;publicstaticTaskRun(objectmessage,IAsyncCollector<SignalRMessage>signalRMessages){returnsignalRMessages.AddAsync(newSignalRMessage{Target="newMessage",Arguments=new[]{message}});}
You can send a message only to connections that have been authenticated to a user by setting the user ID in the SignalR message.
Example function.json:
{ "type": "signalR", "name": "signalRMessages", "hubName": "<hub_name>", "connectionStringSetting": "<name of setting containing SignalR Service connection string>", "direction": "out" }
Here's the C# script code:
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"usingMicrosoft.Azure.WebJobs.Extensions.SignalRService;publicstaticTaskRun(objectmessage,IAsyncCollector<SignalRMessage>signalRMessages){returnsignalRMessages.AddAsync(newSignalRMessage{// the message will only be sent to this user IDUserId="userId1",Target="newMessage",Arguments=new[]{message}});}
You can send a message only to connections that have been added to a group by setting the group name in the SignalR message.
Example function.json:
{ "type": "signalR", "name": "signalRMessages", "hubName": "<hub_name>", "connectionStringSetting": "<name of setting containing SignalR Service connection string>", "direction": "out" }
Here's the C# Script code:
#r "Microsoft.Azure.WebJobs.Extensions.SignalRService"usingMicrosoft.Azure.WebJobs.Extensions.SignalRService;publicstaticTaskRun(objectmessage,IAsyncCollector<SignalRMessage>signalRMessages){returnsignalRMessages.AddAsync(newSignalRMessage{// the message will be sent to the group with this nameGroupName="myGroup",Target="newMessage",Arguments=new[]{message}});}
SignalR Service allows users or connections to be added to groups. Messages can then be sent to a group. You can use the SignalR
output binding to manage groups.
The following example adds a user to a group.
Example function.json
{ "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"usingMicrosoft.Azure.WebJobs.Extensions.SignalRService;publicstaticTaskRun(HttpRequestreq,ClaimsPrincipalclaimsPrincipal,IAsyncCollector<SignalRGroupAction>signalRGroupActions){varuserIdClaim=claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier);returnsignalRGroupActions.AddAsync(newSignalRGroupAction{UserId=userIdClaim.Value,GroupName="myGroup",Action=GroupAction.Add});}
The following example removes a user from a group.
Example function.json
{ "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"usingMicrosoft.Azure.WebJobs.Extensions.SignalRService;publicstaticTaskRun(HttpRequestreq,ClaimsPrincipalclaimsPrincipal,IAsyncCollector<SignalRGroupAction>signalRGroupActions){varuserIdClaim=claimsPrincipal.FindFirst(ClaimTypes.NameIdentifier);returnsignalRGroupActions.AddAsync(newSignalRGroupAction{UserId=userIdClaim.Value,GroupName="myGroup",Action=GroupAction.Remove});}
The following example shows a Twilio output binding in a function.json file and a C# script function that uses the binding. The function uses an out
parameter to send a text message.
Here's binding data in the function.json file:
Example function.json:
{ "type": "twilioSms", "name": "message", "accountSidSetting": "TwilioAccountSid", "authTokenSetting": "TwilioAuthToken", "from": "+1425XXXXXXX", "direction": "out", "body": "Azure Functions Testing" }
Here's C# script code:
#r "Newtonsoft.Json" #r "Twilio" #r "Microsoft.Azure.WebJobs.Extensions.Twilio"usingSystem;usingMicrosoft.Extensions.Logging;usingNewtonsoft.Json;usingMicrosoft.Azure.WebJobs.Extensions.Twilio;usingTwilio.Rest.Api.V2010.Account;usingTwilio.Types;publicstaticvoidRun(stringmyQueueItem,outCreateMessageOptionsmessage,ILoggerlog){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.dynamicorder=JsonConvert.DeserializeObject(myQueueItem);stringmsg="Hello "+order.name+", thank you for your order.";// You must initialize the CreateMessageOptions variable with the "To" phone number.message=newCreateMessageOptions(newPhoneNumber("+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;}
You can't use out parameters in asynchronous code. Here's an asynchronous C# script code example:
#r "Newtonsoft.Json" #r "Twilio" #r "Microsoft.Azure.WebJobs.Extensions.Twilio"usingSystem;usingMicrosoft.Extensions.Logging;usingNewtonsoft.Json;usingMicrosoft.Azure.WebJobs.Extensions.Twilio;usingTwilio.Rest.Api.V2010.Account;usingTwilio.Types;publicstaticasyncTaskRun(stringmyQueueItem,IAsyncCollector<CreateMessageOptions>message,ILoggerlog){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.dynamicorder=JsonConvert.DeserializeObject(myQueueItem);stringmsg="Hello "+order.name+", thank you for your order.";// You must initialize the CreateMessageOptions variable with the "To" phone number.CreateMessageOptionssmsText=newCreateMessageOptions(newPhoneNumber("+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;awaitmessage.AddAsync(smsText);}
The following example shows a warmup trigger in a function.json file and a C# script function that runs on each new instance when it's added to your app.
Not supported for version 1.x of the Functions runtime.
Here's the function.json file:
{ "bindings": [ { "type": "warmupTrigger", "direction": "in", "name": "warmupContext" } ] }
publicstaticvoidRun(WarmupContextwarmupContext,ILoggerlog){log.LogInformation("Function App instance is warm.");}
[!div class="nextstepaction"] Learn more about triggers and bindings
[!div class="nextstepaction"] Learn more about best practices for Azure Functions