Develop Azure Functions using Visual Studio
Visual Studio lets you develop, test, and deploy C# class library functions to Azure. If this experience is your first with Azure Functions, see An introduction to Azure Functions.
Visual Studio provides the following benefits when you develop your functions:
- Edit, build, and run functions on your local development computer.
- Publish your Azure Functions project directly to Azure, and create Azure resources as needed.
- Use C# attributes to declare function bindings directly in the C# code.
- Develop and deploy pre-compiled C# functions. Pre-complied functions provide a better cold-start performance than C# script-based functions.
- Code your functions in C# while having all of the benefits of Visual Studio development.
This article provides details about how to use Visual Studio to develop C# class library functions and publish them to Azure. Before you read this article, consider completing the Functions quickstart for Visual Studio.
Unless otherwise noted, procedures and examples shown are for Visual Studio 2022.
Prerequisites
Azure Functions Tools. To add Azure Function Tools, include the Azure development workload in your Visual Studio installation. If you are using Visual Studio 2017, you may need to follow some additional installation steps.
Other resources that you need, such as an Azure Storage account, are created in your subscription during the publishing process.
-
If you don't have an Azure subscription, create an Azure free account before you begin.
Create an Azure Functions project
The Azure Functions project template in Visual Studio creates a C# class library project that you can publish to a function app in Azure. You can use a function app to group functions as a logical unit for easier management, deployment, scaling, and sharing of resources.
From the Visual Studio menu, select File > New > Project.
In Create a new project, enter functions in the search box, choose the Azure Functions template, and then select Next.
In Configure your new project, enter a Project name for your project, and then select Create. The function app name must be valid as a C# namespace, so don't use underscores, hyphens, or any other nonalphanumeric characters.
For the Create a new Azure Functions application settings, use the values in the following table:
Setting Value Description .NET version .NET 6 This value creates a function project that runs in-process with version 4.x of the Azure Functions runtime. Azure Functions 1.x supports the .NET Framework. For more information, see Azure Functions runtime versions overview. Function template HTTP trigger This value creates a function triggered by an HTTP request. Storage account (AzureWebJobsStorage) Storage emulator Because a function app in Azure requires a storage account, one is assigned or created when you publish your project to Azure. An HTTP trigger doesn't use an Azure Storage account connection string; all other trigger types require a valid Azure Storage account connection string. Authorization level Anonymous The created function can be triggered by any client without providing a key. This authorization setting makes it easy to test your new function. For more information about keys and authorization, see Authorization keys and HTTP and webhook bindings. 
Make sure you set the Authorization level to Anonymous. If you choose the default level of Function, you're required to present the function key in requests to access your function endpoint.
Select Create to create the function project and HTTP trigger function.
After you create an Azure Functions project, the project template creates a C# project, installs the Microsoft.NET.Sdk.Functions NuGet package, and sets the target framework. The new project has the following files:
host.json: Lets you configure the Functions host. These settings apply both when running locally and in Azure. For more information, see host.json reference.
local.settings.json: Maintains settings used when running functions locally. These settings aren't used when running in Azure. For more information, see Local settings file.
Important
Because the local.settings.json file can contain secrets, you must exclude it from your project source control. Make sure the Copy to Output Directory setting for this file is set to Copy if newer.
For more information, see Functions class library project.
Local settings
When running in a function app in Azure, settings required by your functions are stored securely in app settings. During local development, these settings are instead added to the Values object in the local.settings.json file. The local.settings.json file also stores settings used by local development tools.
Because the local.settings.json may contain secrets, such as connection strings, you should never store it in a remote repository. To learn more about local settings, see Local settings file.
Visual Studio doesn't automatically upload the settings in local.settings.json when you publish the project. To make sure that these settings also exist in your function app in Azure, upload them after you publish your project. For more information, see Function app settings. The values in a ConnectionStrings collection are never published.
Your code can also read the function app settings values as environment variables. For more information, see Environment variables.
Configure the project for local development
The Functions runtime uses an Azure Storage account internally. For all trigger types other than HTTP and webhooks, set the Values.AzureWebJobsStorage key to a valid Azure Storage account connection string. Your function app can also use the Azure Storage Emulator for the AzureWebJobsStorage connection setting that's required by the project. To use the emulator, set the value of AzureWebJobsStorage to UseDevelopmentStorage=true. Change this setting to an actual storage account connection string before deployment.
To set the storage account connection string:
In the Azure portal, navigate to your storage account.
In the Access keys tab, below Security + networking, copy the Connection string of key1.
In your project, open the local.settings.json file and set the value of the
AzureWebJobsStoragekey to the connection string you copied.Repeat the previous step to add unique keys to the
Valuesarray for any other connections required by your functions.
Add a function to your project
In C# class library functions, the bindings used by the function are defined by applying attributes in the code. When you create your function triggers from the provided templates, the trigger attributes are applied for you.
In Solution Explorer, right-click your project node and select Add > New Item.
Select Azure Function, enter a Name for the class, and then select Add.
Choose your trigger, set the binding properties, and then select Add. The following example shows the settings for creating a Queue storage trigger function.

You will then be prompted to choose between two Azure storage emulators or referencing a provisioned Azure storage account.
This trigger example uses a connection string with a key named
QueueStorage. This key, stored in the local.settings.json file, either references the Azure storage emulators or an Azure storage account.Examine the newly added class. You see a static
Run()method that's attributed with theFunctionNameattribute. This attribute indicates that the method is the entry point for the function.For example, the following C# class represents a basic Queue storage trigger function:
using System; using Microsoft.Azure.WebJobs; using Microsoft.Azure.WebJobs.Host; using Microsoft.Extensions.Logging; namespace FunctionApp1 { public static class Function1 { [FunctionName("QueueTriggerCSharp")] public static void Run([QueueTrigger("myqueue-items", Connection = "QueueStorage")]string myQueueItem, ILogger log) { log.LogInformation($"C# Queue trigger function processed: {myQueueItem}"); } } }
A binding-specific attribute is applied to each binding parameter supplied to the entry point method. The attribute takes the binding information as parameters. In the previous example, the first parameter has a QueueTrigger attribute applied, indicating a Queue storage trigger function. The queue name and connection string setting name are passed as parameters to the QueueTrigger attribute. For more information, see Azure Queue storage bindings for Azure Functions.
Use the above procedure to add more functions to your function app project. Each function in the project can have a different trigger, but a function must have exactly one trigger. For more information, see Azure Functions triggers and bindings concepts.
Add bindings
As with triggers, input and output bindings are added to your function as binding attributes. Add bindings to a function as follows:
Make sure you've configured the project for local development.
Add the appropriate NuGet extension package for the specific binding by finding the binding-specific NuGet package requirements in the reference article for the binding. For example, find package requirements for the Event Hubs trigger in the Event Hubs binding reference article.
Use the following command in the Package Manager Console to install a specific package:
Install-Package Microsoft.Azure.WebJobs.Extensions.<BINDING_TYPE> -Version <TARGET_VERSION>In this example replace
<BINDING_TYPE>with the name specific to the binding extension and<TARGET_VERSION>with a specific version of the package, such as3.0.0-beta5. Valid versions are listed on the individual package pages at NuGet.org. The major versions that correspond to Functions runtime 1.x or 2.x are specified in the reference article for the binding.If there are app settings that the binding needs, add them to the
Valuescollection in the local setting file.The function uses these values when it runs locally. When the function runs in the function app in Azure, it uses the function app settings.
Add the appropriate binding attribute to the method signature. In the following example, a queue message triggers the function, and the output binding creates a new queue message with the same text in a different queue.
public static class SimpleExampleWithOutput { [FunctionName("CopyQueueMessage")] public static void Run( [QueueTrigger("myqueue-items-source", Connection = "AzureWebJobsStorage")] string myQueueItem, [Queue("myqueue-items-destination", Connection = "AzureWebJobsStorage")] out string myQueueItemCopy, ILogger log) { log.LogInformation($"CopyQueueMessage function processed: {myQueueItem}"); myQueueItemCopy = myQueueItem; } }The connection to Queue storage is obtained from the
AzureWebJobsStoragesetting. For more information, see the reference article for the specific binding.
For a full list of the bindings supported by Functions, see Supported bindings.
Run functions locally
Azure Functions Core Tools lets you run Azure Functions project on your local development computer. When you press F5 to debug a Functions project, the local Functions host (func.exe) starts to listen on a local port (usually 7071). Any callable function endpoints are written to the output, and you can use these for testing your functions. For more information, see Work with Azure Functions Core Tools. You're prompted to install these tools the first time you start a function from Visual Studio.
To start your function in Visual Studio in debug mode:
Press F5. If prompted, accept the request from Visual Studio to download and install Azure Functions Core (CLI) tools. You might also need to enable a firewall exception so that the tools can handle HTTP requests.
With the project running, test your code as you would test a deployed function.
When you run Visual Studio in debug mode, breakpoints are hit as expected.
For a more detailed testing scenario using Visual Studio, see Testing functions.
Publish to Azure
When you publish from Visual Studio, it uses one of the two deployment methods:
- Web Deploy: Packages and deploys Windows apps to any IIS server.
- Zip Deploy with run-From-package enabled: Recommended for Azure Functions deployments.
Use the following steps to publish your project to a function app in Azure.
In Solution Explorer, right-click the project and select Publish. In Target, select Azure then Next.
For the Specific target, choose Azure Function App (Windows), which creates a function app that runs on Windows.
In Function Instance, choose Create a new Azure Function...
Create a new instance using the values specified in the following table:
Setting Value Description Name Globally unique name Name that uniquely identifies your new function app. Accept this name or enter a new name. Valid characters are: a-z,0-9, and-.Subscription Your subscription The Azure subscription to use. Accept this subscription or select a new one from the drop-down list. Resource group Name of your resource group The resource group in which to create your function app. Select an existing resource group from the drop-down list or choose New to create a new resource group. Plan Type Consumption When you publish your project to a function app that runs in a Consumption plan, you pay only for executions of your functions app. Other hosting plans incur higher costs. Location Location of the app service Choose a Location in a region near you or other services your functions access. Azure Storage General-purpose storage account An Azure Storage account is required by the Functions runtime. Select New to configure a general-purpose storage account. You can also choose an existing account that meets the storage account requirements. 
Select Create to create a function app and its related resources in Azure. Status of resource creation is shown in the lower left of the window.
Back in Functions instance, make sure that Run from package file is checked. Your function app is deployed using Zip Deploy with Run-From-Package mode enabled. This is the recommended deployment method for your functions project, since it results in better performance.
Select Finish, and on the Publish page, select Publish to deploy the package containing your project files to your new function app in Azure.
After the deployment completes, the root URL of the function app in Azure is shown in the Publish tab.
In the Publish tab, in the Hosting section, choose Open in Azure portal. This opens the new function app Azure resource in the Azure portal.
Function app settings
Visual Studio doesn't upload these settings automatically when you publish the project. Any settings you add in the local.settings.json you must also add to the function app in Azure.
The easiest way to upload the required settings to your function app in Azure is to expand the three dots next to the Hosting section and select the Manage Azure App Service settings link that appears after you successfully publish your project.
Selecting this link displays the Application settings dialog for the function app, where you can add new application settings or modify existing ones.

Local displays a setting value in the local.settings.json file, and Remote displays a current setting value in the function app in Azure. Choose Add setting to create a new app setting. Use the Insert value from Local link to copy a setting value to the Remote field. Pending changes are written to the local settings file and the function app when you select OK.
Note
By default, the local.settings.json file is not checked into source control. This means that if you clone a local Functions project from source control, the project doesn't have a local.settings.json file. In this case, you need to manually create the local.settings.json file in the project root so that the Application settings dialog works as expected.
You can also manage application settings in one of these other ways:
- Use the Azure portal.
- Use the
--publish-local-settingspublish option in the Azure Functions Core Tools. - Use the Azure CLI.
Monitoring functions
The recommended way to monitor the execution of your functions is by integrating your function app with Azure Application Insights. When you create a function app in the Azure portal, this integration is done for you by default. However, when you create your function app during Visual Studio publishing, the integration in your function app in Azure isn't done. To learn how to connect Application Insights to your function app, see Enable Application Insights integration.
To learn more about monitoring using Application Insights, see Monitor Azure Functions.
Testing functions
This section describes how to create a C# function app project in Visual Studio and to run and test with xUnit.

Setup
To set up your environment, create a function and test the app. The following steps help you create the apps and functions required to support the tests:
- Create a new Functions app and name it Functions
- Create an HTTP function from the template and name it MyHttpTrigger.
- Create a timer function from the template and name it MyTimerTrigger.
- Create an xUnit Test app in the solution and name it Functions.Tests. Remove the default test files.
- Use NuGet to add a reference from the test app to Microsoft.AspNetCore.Mvc
- Reference the Functions app from Functions.Tests app.
Create test classes
Now that the projects are created, you can create the classes used to run the automated tests.
Each function takes an instance of ILogger to handle message logging. Some tests either don't log messages or have no concern for how logging is implemented. Other tests need to evaluate messages logged to determine whether a test is passing.
You'll create a new class named ListLogger, which holds an internal list of messages to evaluate during testing. To implement the required ILogger interface, the class needs a scope. The following class mocks a scope for the test cases to pass to the ListLogger class.
Create a new class in Functions.Tests project named NullScope.cs and enter the following code:
using System;
namespace Functions.Tests
{
public class NullScope : IDisposable
{
public static NullScope Instance { get; } = new NullScope();
private NullScope() { }
public void Dispose() { }
}
}
Next, create a new class in Functions.Tests project named ListLogger.cs and enter the following code:
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Text;
namespace Functions.Tests
{
public class ListLogger : ILogger
{
public IList<string> Logs;
public IDisposable BeginScope<TState>(TState state) => NullScope.Instance;
public bool IsEnabled(LogLevel logLevel) => false;
public ListLogger()
{
this.Logs = new List<string>();
}
public void Log<TState>(LogLevel logLevel,
EventId eventId,
TState state,
Exception exception,
Func<TState, Exception, string> formatter)
{
string message = formatter(state, exception);
this.Logs.Add(message);
}
}
}
The ListLogger class implements the following members as contracted by the ILogger interface:
BeginScope: Scopes add context to your logging. In this case, the test just points to the static instance on the
NullScopeclass to allow the test to function.IsEnabled: A default value of
falseis provided.Log: This method uses the provided
formatterfunction to format the message and then adds the resulting text to theLogscollection.
The Logs collection is an instance of List<string> and is initialized in the constructor.
Next, create a new file in Functions.Tests project named LoggerTypes.cs and enter the following code:
namespace Functions.Tests
{
public enum LoggerTypes
{
Null,
List
}
}
This enumeration specifies the type of logger used by the tests.
Now create a new class in Functions.Tests project named TestFactory.cs and enter the following code:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Internal;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Primitives;
using System.Collections.Generic;
namespace Functions.Tests
{
public class TestFactory
{
public static IEnumerable<object[]> Data()
{
return new List<object[]>
{
new object[] { "name", "Bill" },
new object[] { "name", "Paul" },
new object[] { "name", "Steve" }
};
}
private static Dictionary<string, StringValues> CreateDictionary(string key, string value)
{
var qs = new Dictionary<string, StringValues>
{
{ key, value }
};
return qs;
}
public static HttpRequest CreateHttpRequest(string queryStringKey, string queryStringValue)
{
var context = new DefaultHttpContext();
var request = context.Request;
request.Query = new QueryCollection(CreateDictionary(queryStringKey, queryStringValue));
return request;
}
public static ILogger CreateLogger(LoggerTypes type = LoggerTypes.Null)
{
ILogger logger;
if (type == LoggerTypes.List)
{
logger = new ListLogger();
}
else
{
logger = NullLoggerFactory.Instance.CreateLogger("Null Logger");
}
return logger;
}
}
}
The TestFactory class implements the following members:
Data: This property returns an IEnumerable collection of sample data. The key value pairs represent values that are passed into a query string.
CreateDictionary: This method accepts a key/value pair as arguments and returns a new
Dictionaryused to createQueryCollectionto represent query string values.CreateHttpRequest: This method creates an HTTP request initialized with the given query string parameters.
CreateLogger: Based on the logger type, this method returns a logger class used for testing. The
ListLoggerkeeps track of logged messages available for evaluation in tests.
Finally, create a new class in Functions.Tests project named FunctionsTests.cs and enter the following code:
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Xunit;
namespace Functions.Tests
{
public class FunctionsTests
{
private readonly ILogger logger = TestFactory.CreateLogger();
[Fact]
public async void Http_trigger_should_return_known_string()
{
var request = TestFactory.CreateHttpRequest("name", "Bill");
var response = (OkObjectResult)await MyHttpTrigger.Run(request, logger);
Assert.Equal("Hello, Bill. This HTTP triggered function executed successfully.", response.Value);
}
[Theory]
[MemberData(nameof(TestFactory.Data), MemberType = typeof(TestFactory))]
public async void Http_trigger_should_return_known_string_from_member_data(string queryStringKey, string queryStringValue)
{
var request = TestFactory.CreateHttpRequest(queryStringKey, queryStringValue);
var response = (OkObjectResult)await MyHttpTrigger.Run(request, logger);
Assert.Equal($"Hello, {queryStringValue}. This HTTP triggered function executed successfully.", response.Value);
}
[Fact]
public void Timer_should_log_message()
{
var logger = (ListLogger)TestFactory.CreateLogger(LoggerTypes.List);
new MyTimerTrigger().Run(null, logger);
var msg = logger.Logs[0];
Assert.Contains("C# Timer trigger function executed at", msg);
}
}
}
The members implemented in this class are:
Http_trigger_should_return_known_string: This test creates a request with the query string values of
name=Billto an HTTP function and checks that the expected response is returned.Http_trigger_should_return_string_from_member_data: This test uses xUnit attributes to provide sample data to the HTTP function.
Timer_should_log_message: This test creates an instance of
ListLoggerand passes it to a timer function. Once the function is run, then the log is checked to make sure the expected message is present.
If you want to access application settings in your tests, you can inject an IConfiguration instance with mocked environment variable values into your function.
Run tests
To run the tests, navigate to the Test Explorer and select Run All Tests in View.

Debug tests
To debug the tests, set a breakpoint on a test, navigate to the Test Explorer and select Run > Debug Last Run.
Azure Functions tools with Visual Studio 2017
Azure Functions Tools is available in the Azure development workload starting with Visual Studio 2017. In Visual Studio 2017, the Azure development workload installs Azure Functions Tools as a separate extension. In Visual Studio 2019 and later, the Azure Functions tools extension is updated as part of Visual Studio.
When you update your Visual Studio 2017 installation, make sure that you're using the most recent version of the Azure Functions Tools. The following sections show you how to check and (if needed) update your Azure Functions Tools extension in Visual Studio 2017.
Check your tools version in Visual Studio 2017
From the Tools menu, choose Extensions and Updates. Expand Installed > Tools, and then choose Azure Functions and Web Jobs Tools.

Note the installed Version and compare this version with the latest version listed in the release notes.
If your version is older, update your tools in Visual Studio as shown in the following section.
Update your tools in Visual Studio 2017
In the Extensions and Updates dialog, expand Updates > Visual Studio Marketplace, choose Azure Functions and Web Jobs Tools and select Update.

After the tools update is downloaded, select Close, and then close Visual Studio to trigger the tools update with VSIX Installer.
In VSIX Installer, choose Modify to update the tools.
After the update is complete, choose Close, and then restart Visual Studio.
Next steps
For more information about the Azure Functions Core Tools, see Work with Azure Functions Core Tools.
For more information about developing functions as .NET class libraries, see Azure Functions C# developer reference. This article also links to examples on how to use attributes to declare the various types of bindings supported by Azure Functions.
Maklum balas
Kirim dan lihat maklum balas untuk
