Using .NET class libraries with Azure Functions

In addition to script files, Azure Functions supports publishing a class library as the implementation for one or more functions. We recommend that you use the Azure Functions Visual Studio 2017 Tools.

Prerequisites

This article has the following prerequisites:

Functions class library project

From Visual Studio, create a new Azure Functions project. The new project template creates the files host.json and local.settings.json. You can customize Azure Functions runtime settings in host.json.

The file local.settings.json stores app settings, connection strings, and settings for Azure Functions Core Tools. To learn more about its structure, see Code and test Azure functions locally.

FunctionName attribute

The attribute FunctionNameAttribute marks a method as a function entry point. It must be used with exactly one trigger and 0 or more input and output bindings.

Conversion to function.json

When you build an Azure Functions project, a function.json file is created in the function's directory. The directory name is the same as the function name that the [FunctionName] attribute specifies. The function.json file contains triggers and bindings and points to the project assembly file.

This conversion is performed by the NuGet package Microsoft.NET.Sdk.Functions. The source is available in the GitHub repo azure-functions-vs-build-sdk.

Triggers and bindings

The following table lists the triggers and bindings that are available in an Azure Functions class library project. All attributes are in the namespace Microsoft.Azure.WebJobs.

Binding Attribute NuGet package
Blob storage trigger, input, output BlobAttribute, StorageAccountAttribute Microsoft.Azure.WebJobs
Cosmos DB trigger CosmosDBTriggerAttribute Microsoft.Azure.WebJobs.Extensions.DocumentDB
Cosmos DB input and output DocumentDBAttribute Microsoft.Azure.WebJobs.Extensions.DocumentDB
Event Hubs trigger and output EventHubTriggerAttribute, EventHubAttribute Microsoft.Azure.WebJobs.ServiceBus
External file input and output ApiHubFileAttribute Microsoft.Azure.WebJobs.Extensions.ApiHub
HTTP and webhook trigger HttpTriggerAttribute Microsoft.Azure.WebJobs.Extensions.Http
Mobile Apps input and output MobileTableAttribute Microsoft.Azure.WebJobs.Extensions.MobileApps
Notification Hubs output NotificationHubAttribute Microsoft.Azure.WebJobs.Extensions.NotificationHubs
Queue storage trigger and output QueueAttribute, StorageAccountAttribute Microsoft.Azure.WebJobs
SendGrid output SendGridAttribute Microsoft.Azure.WebJobs.Extensions.SendGrid
Service Bus trigger and output ServiceBusAttribute, ServiceBusAccountAttribute Microsoft.Azure.WebJobs.ServiceBus
Table storage input and output TableAttribute, StorageAccountAttribute Microsoft.Azure.WebJobs
Timer trigger TimerTriggerAttribute Microsoft.Azure.WebJobs.Extensions
Twilio output TwilioSmsAttribute Microsoft.Azure.WebJobs.Extensions.Twilio

Blob storage trigger, input bindings, and output bindings

Azure Functions supports trigger, input, and output bindings for Azure Blob storage. For more information on binding expressions and metadata, see Azure Functions Blob storage bindings.

A blob trigger is defined with the [BlobTrigger] attribute. You can use the attribute [StorageAccount] to define the app setting name that contains the connection string to the storage account that is used by an entire function or class.

[StorageAccount("AzureWebJobsStorage")]
[FunctionName("BlobTriggerCSharp")]        
public static void Run([BlobTrigger("samples-workitems/{name}")] Stream myBlob, string name, TraceWriter log)
{
    log.Info($"C# Blob trigger function Processed blob\n Name:{name} \n Size: {myBlob.Length} Bytes");
}

Blob input and output are defined using the [Blob] attribute, along with a FileAccess parameter indicating read or write. The following example uses a blob trigger and blob output binding.

[FunctionName("ResizeImage")]
[StorageAccount("AzureWebJobsStorage")]
public static void Run(
    [BlobTrigger("sample-images/{name}")] Stream image, 
    [Blob("sample-images-sm/{name}", FileAccess.Write)] Stream imageSmall, 
    [Blob("sample-images-md/{name}", FileAccess.Write)] Stream imageMedium)
{
    var imageBuilder = ImageResizer.ImageBuilder.Current;
    var size = imageDimensionsTable[ImageSize.Small];

    imageBuilder.Build(image, imageSmall,
        new ResizeSettings(size.Item1, size.Item2, FitMode.Max, null), false);

    image.Position = 0;
    size = imageDimensionsTable[ImageSize.Medium];

    imageBuilder.Build(image, imageMedium,
        new ResizeSettings(size.Item1, size.Item2, FitMode.Max, null), false);
}

public enum ImageSize { ExtraSmall, Small, Medium }

private static Dictionary<ImageSize, (int, int)> imageDimensionsTable = new Dictionary<ImageSize, (int, int)>() {
    { ImageSize.ExtraSmall, (320, 200) },
    { ImageSize.Small,      (640, 400) },
    { ImageSize.Medium,     (800, 600) }
};

Cosmos DB trigger, input bindings, and output bindings

Azure Functions supports triggers and input and output bindings for Cosmos DB. To learn more about the features of the Cosmos DB binding, see Azure Functions Cosmos DB bindings.

To trigger from a Cosmos DB document, use the attribute [CosmosDBTrigger] in the NuGet package Microsoft.Azure.WebJobs.Extensions.DocumentDB. The following example triggers from a specific database and collection. The setting myCosmosDB contains the connection to the Cosmos DB instance.

[FunctionName("DocumentUpdates")]
public static void Run(
    [CosmosDBTrigger("database", "collection", ConnectionStringSetting = "myCosmosDB")]
IReadOnlyList<Document> documents, TraceWriter log)
{
        log.Info("Documents modified " + documents.Count);
        log.Info("First document Id " + documents[0].Id);
}

To bind to a Cosmos DB document, use the attribute [DocumentDB] in the NuGet package Microsoft.Azure.WebJobs.Extensions.DocumentDB. The following example has a queue trigger and a DocumentDB API output binding.

[FunctionName("QueueToDocDB")]        
public static void Run(
    [QueueTrigger("myqueue-items", Connection = "AzureWebJobsStorage")] string myQueueItem, 
    [DocumentDB("ToDoList", "Items", ConnectionStringSetting = "myCosmosDB")] out dynamic document)
{
    document = new { Text = myQueueItem, id = Guid.NewGuid() };
}

Event Hubs trigger and output

Azure Functions supports trigger and output bindings for Event Hubs. For more information, see Azure Functions Event Hub bindings.

The types [Microsoft.Azure.WebJobs.ServiceBus.EventHubTriggerAttribute] and [Microsoft.Azure.WebJobs.ServiceBus.EventHubAttribute] are defined in the NuGet package Microsoft.Azure.WebJobs.ServiceBus.

The following example uses an Event Hub trigger:

[FunctionName("EventHubTriggerCSharp")]
public static void Run([EventHubTrigger("samples-workitems", Connection = "EventHubConnection")] string myEventHubMessage, TraceWriter log)
{
    log.Info($"C# Event Hub trigger function processed a message: {myEventHubMessage}");
}

The following example has an Event Hub output, using the method return value as the output:

[FunctionName("EventHubOutput")]
[return: EventHub("outputEventHubMessage", Connection = "EventHubConnection")]
public static string Run([TimerTrigger("0 */5 * * * *")] TimerInfo myTimer, TraceWriter log)
{
    log.Info($"C# Timer trigger function executed at: {DateTime.Now}");
    return $"{DateTime.Now}";
}

External file input and output

Azure Functions supports trigger, input, and output bindings for external files, such as Google Drive, Dropbox, and OneDrive. To learn more, see Azure Functions External File bindings. The attributes [ExternalFileTrigger] and [ExternalFile] are defined in the NuGet package Microsoft.Azure.WebJobs.Extensions.ApiHub.

The following C# example demonstrates an external file input and output binding. The code copies the input file to the output file.

[StorageAccount("MyStorageConnection")]
[FunctionName("ExternalFile")]
[return: ApiHubFile("MyFileConnection", "samples-workitems/{queueTrigger}-Copy", FileAccess.Write)]
public static string Run([QueueTrigger("myqueue-items")] string myQueueItem, 
    [ApiHubFile("MyFileConnection", "samples-workitems/{queueTrigger}", FileAccess.Read)] string myInputFile, 
    TraceWriter log)
{
    log.Info($"C# Queue trigger function processed: {myQueueItem}");
    return myInputFile;
}

HTTP and webhooks

Use the HttpTrigger attribute to define an HTTP trigger or webhook. This attribute is defined in the NuGet package Microsoft.Azure.WebJobs.Extensions.Http. You can customize the authorization level, webhook type, route, and methods. The following example defines an HTTP trigger with anonymous authentication and genericJson webhook type.

[FunctionName("HttpTriggerCSharp")]
public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Anonymous, WebHookType = "genericJson")] HttpRequestMessage req)
{
    return req.CreateResponse(HttpStatusCode.OK);
}

Mobile Apps input and output

Azure Functions supports input and output bindings for Mobile Apps. To learn more, see Azure Functions Mobile Apps bindings. The attribute [MobileTable] is defined in the NuGet package Microsoft.Azure.WebJobs.Extensions.MobileApps.

The following example demonstrates a Mobile Apps output binding:

[FunctionName("MobileAppsOutput")]        
[return: MobileTable(ApiKeySetting = "MyMobileAppKey", TableName = "MyTable", MobileAppUriSetting = "MyMobileAppUri")]
public static object Run([QueueTrigger("myqueue-items", Connection = "AzureWebJobsStorage")] string myQueueItem, TraceWriter log)
{
    return new { Text = $"I'm running in a C# function! {myQueueItem}" };
}

Notification Hubs output

Azure Functions supports an output binding for Notification Hubs. To learn more, see Azure Functions Notification Hub output binding. The attribute [NotificationHub] is defined in the NuGet package Microsoft.Azure.WebJobs.Extensions.NotificationHubs.

Queue storage trigger and output

Azure Functions supports trigger and output bindings for Azure queues. For more information, see Azure Functions Queue Storage bindings.

The following example shows how to use the function return type with a queue output binding, using the [Queue] attribute.

[StorageAccount("AzureWebJobsStorage")]
public static class QueueFunctions
{
    // HTTP trigger with queue output binding
    [FunctionName("QueueOutput")]
    [return: Queue("myqueue-items")]
    public static string QueueOutput([HttpTrigger] dynamic input,  TraceWriter log)
    {
        log.Info($"C# function processed: {input.Text}");
        return input.Text;
    }
}

To define a queue trigger, use the [QueueTrigger] attribute.

[StorageAccount("AzureWebJobsStorage")]
public static class QueueFunctions
{
    // Queue trigger
    [FunctionName("QueueTrigger")]
    [StorageAccount("AzureWebJobsStorage")]
    public static void QueueTrigger([QueueTrigger("myqueue-items")] string myQueueItem, TraceWriter log)
    {
        log.Info($"C# function processed: {myQueueItem}");
    }
}

SendGrid output

Azure Functions supports a SendGrid output binding for sending email programmatically. To learn more, see Azure Functions SendGrid bindings.

The attribute [SendGrid] is defined in the NuGet package Microsoft.Azure.WebJobs.Extensions.SendGrid. A SendGrid binding requires an application setting named AzureWebJobsSendGridApiKey, which contains your SendGrid API key. This is the default setting name for your SendGrid API key. If you need to have more than one SendGrid key or choose a different setting name, you can set this name using the ApiKey property of the SendGrid binding attribute, as in the following example:

[SendGrid(ApiKey = "MyCustomSendGridKeyName")]

The following is an example of using a Service Bus queue trigger and a SendGrid output binding using SendGridMessage:

[FunctionName("SendEmail")]
public static void Run(
    [ServiceBusTrigger("myqueue", AccessRights.Manage, Connection = "ServiceBusConnection")] OutgoingEmail email,
    [SendGrid] out SendGridMessage message)
{
    message = new SendGridMessage();
    message.AddTo(email.To);
    message.AddContent("text/html", email.Body);
    message.SetFrom(new EmailAddress(email.From));
    message.SetSubject(email.Subject);
}

public class OutgoingEmail
{
    public string To { get; set; }
    public string From { get; set; }
    public string Subject { get; set; }
    public string Body { get; set; }
}

Note that this example requires the SendGrid API key to be storage in an application setting named AzureWebJobsSendGridApiKey.

Service Bus trigger and output

Azure Functions supports trigger and output bindings for Service Bus queues and topics. For more information on configuring bindings, see Azure Functions Service Bus bindings.

The attributes [ServiceBusTrigger] and [ServiceBus] are defined in the NuGet package Microsoft.Azure.WebJobs.ServiceBus.

The following is an example of a Service Bus queue trigger:

[FunctionName("ServiceBusQueueTriggerCSharp")]                    
public static void Run([ServiceBusTrigger("myqueue", AccessRights.Manage, Connection = "ServiceBusConnection")] string myQueueItem, TraceWriter log)
{
    log.Info($"C# ServiceBus queue trigger function processed message: {myQueueItem}");
}

The following is an example of a Service Bus output binding, using the method return type as the output:

[FunctionName("ServiceBusOutput")]
[return: ServiceBus("myqueue", Connection = "ServiceBusConnection")]
public static string ServiceBusOutput([HttpTrigger] dynamic input, TraceWriter log)
{
    log.Info($"C# function processed: {input.Text}");
    return input.Text;
}

Table storage input and output

Azure Functions supports input and output bindings for Azure Table storage. To learn more, see Azure Functions Table storage bindings.

The following example is a class with two functions, demonstrating table storage output and input bindings.

[StorageAccount("AzureWebJobsStorage")]
public class TableStorage
{
    public class MyPoco
    {
        public string PartitionKey { get; set; }
        public string RowKey { get; set; }
        public string Text { get; set; }
    }

    [FunctionName("TableOutput")]
    [return: Table("MyTable")]
    public static MyPoco TableOutput([HttpTrigger] dynamic input, TraceWriter log)
    {
        log.Info($"C# http trigger function processed: {input.Text}");
        return new MyPoco { PartitionKey = "Http", RowKey = Guid.NewGuid().ToString(), Text = input.Text };
    }

    // use the metadata parameter "queueTrigger" to bind the queue payload
    [FunctionName("TableInput")]
    public static void TableInput([QueueTrigger("table-items")] string input, [Table("MyTable", "Http", "{queueTrigger}")] MyPoco poco, TraceWriter log)
    {
        log.Info($"C# function processed: {poco.Text}");
    }
}

Timer trigger

Azure Functions has a timer trigger binding that lets you run your function code based on a defined schedule. To learn more about the features of the binding, see Schedule code execution with Azure Functions.

On the Consumption plan, you can define schedules with a CRON expression. If you're using an App Service Plan, you can also use a TimeSpan string.

The following example defines a timer trigger that runs every five minutes:

[FunctionName("TimerTriggerCSharp")]
public static void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, TraceWriter log)
{
    log.Info($"C# Timer trigger function executed at: {DateTime.Now}");
}

Twilio output

Azure Functions supports Twilio output bindings to enable your functions to send SMS text messages. To learn more, see Send SMS messages from Azure Functions using the Twilio output binding.

The attribute [TwilioSms] is defined in the package Microsoft.Azure.WebJobs.Extensions.Twilio.

The following C# example uses a queue trigger and a Twilio output binding:

[FunctionName("QueueTwilio")]
[return: TwilioSms(AccountSidSetting = "TwilioAccountSid", AuthTokenSetting = "TwilioAuthToken", From = "+1425XXXXXXX" )]
public static SMSMessage Run([QueueTrigger("myqueue-items", Connection = "AzureWebJobsStorage")] JObject order, TraceWriter log)
{
    log.Info($"C# Queue trigger function processed: {order}");

    var message = new SMSMessage()
    {
        Body = $"Hello {order["name"]}, thanks for your order!",
        To = order["mobileNumber"].ToString()
    };

    return message;
}

Next steps

For more information on using Azure Functions in C# scripting, see Azure Functions C# script developer reference.

For information about other bindings and triggers for Azure Functions, see Azure Functions triggers and bindings developer reference.