C# developer reference for Azure Functions

This article provides a C# developer reference for Azure Functions. Azure Functions can be written in several languages, including C#. This reference covers key concepts, language-specific details, and best practices for developing C# functions.

Note: Azure Functions supports C# in two primary ways:
  • In-process model: Functions run within the same process as the Functions host. This is the default for .NET 6+ functions and offers the best performance.
  • Isolated worker model: Functions run in a separate process from the Functions host. This model provides greater flexibility, allowing you to use different .NET versions and have more control over the execution environment.

Core Concepts for C# Functions

Function Triggers and Bindings

Triggers and bindings are fundamental to Azure Functions, allowing your functions to respond to events and interact with other Azure services and external systems without writing explicit integration code. In C#, these are typically defined using attributes.

Example: HTTP Trigger with Input Binding

The following example shows a C# HTTP-triggered function that also uses an input binding to read a message from Azure Queue Storage.


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

public static class HttpTriggerQueueInput
{
    [FunctionName("HttpTriggerQueueInput")]
    public static async Task<IActionResult> Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
        [Queue("myqueue-items")] string queueMessage, // Input binding to read a queue message
        ILogger log)
    {
        log.LogInformation("C# HTTP trigger function processed a request.");

        string name = req.Query["name"];
        string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
        dynamic data = JsonConvert.DeserializeObject(requestBody);
        name = name ?? data?.name;

        string responseMessage = string.IsNullOrEmpty(name)
            ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
            : $"Hello, {name}! The message from the queue is: '{queueMessage}'.";

        return new OkObjectResult(responseMessage);
    }
}
            

Function Host and Runtime

The Functions host manages the execution of your functions. For C# functions, this involves loading your code, managing dependencies, and handling trigger invocations.

Dependency Injection

Azure Functions (especially in the isolated worker model) extensively uses dependency injection. You can inject services like ILogger, HttpClient, and custom services into your function constructors or methods.

Tip: Use the Microsoft.Extensions.DependencyInjection package for advanced DI scenarios.

Configuration

You can manage configuration settings for your C# functions using application settings. These are accessible via environment variables or the IConfiguration service.


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

        // Accessing configuration settings (e.g., from local.settings.json or app settings)
        var config = new ConfigurationBuilder()
            .SetBasePath(context.FunctionDirectory)
            .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
            .AddEnvironmentVariables()
            .Build();

        string mySetting = config["MyCustomSetting"];
        log.LogInformation($"MyCustomSetting value: {mySetting}");
    }
}
            

Common C# Function Scenarios

Working with HTTP Requests

HTTP-triggered functions are the most common type. They can handle GET, POST, PUT, DELETE, and other HTTP methods. The HttpRequest object provides access to request headers, body, query parameters, and route parameters.

Timer-Triggered Functions

Timer triggers allow you to schedule function executions at regular intervals. The schedule is defined using a CRON expression.

Storage Triggers and Bindings

Functions can interact with Azure Storage services like Blob Storage, Queue Storage, and Table Storage. Input bindings can read data, and output bindings can write data.

Cosmos DB Integration

Azure Functions provides built-in bindings for Azure Cosmos DB, enabling you to read documents or trigger functions based on changes in a Cosmos DB container.

Best Practices for C# Functions

Next Steps