#SharePointProblems | Koskila.net

Solutions are worthless unless shared! Antti K. Koskela's Personal Professional Blog
>

How to get application settings for your Azure Function App using C#?

koskila
Reading Time 9 min
Word Count 1544 words
Comments 16 comments
Rating 5 (2 votes)
View

This article explains how you can access an Azure Function's Application/Environment settings/variables from your C# code. Different versions of Azure Functions have different ways to access the Azure Function settings, but this page should explain the easiest way to get your application setting values for each Azure Functions version!

While this is something I need often, it has been another little thing, that I always forget - so better document it somewhere.

How to get application settings in different runtime versions of Azure Functions?

This has changed between different versions of Azure Functions runtime - so I'm describing what should work for v4 (the latest runtime version), v3, v2, and v1.

Note, that a lot of the examples below are not entirely specific to Azure Functions - they show how to access app.config or local.settings.json values in C# regardless of the exact implementation, whether it's a webjob, ASP.NET application, .NET Console program, or something else. This post is written from Azure Functions' viewpoint, though.

Accessing the settings in Azure Functions Runtime Versions 3 & 4

Okay, so if you'll take a look at the way the Application Settings (or whatever you want to call them) are accessed for the v2 runtime of Azure Functions, you can see they made it extremely granular. It's very functional, but it can be a bit of a pain in the behind when just setting up one function.

Now, in v3 they made it far more straightforward! And luckily, they kept this configuration for v4 as well.

The example below shouldn't require any NuGet packages, and it just works!

Awesome! Just update your using statements like shown:

// C# ConfigurationBuilder example for Azure Functions v3 or v4 runtime
using System;
using System.IO;

// you'll need this:
using Microsoft.Extensions.Configuration; 

namespace YourApp
{
 public static class YourClass
 {
    
  [FunctionName("FunctionName")]
  public static async Task<IActionResult> Run(
   [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,
   // You'll need this to add the 
   // local.settings.json file for local execution:
   ExecutionContext context, 
   ILogger log)
  {
   var config = new ConfigurationBuilder()
   .SetBasePath(context.FunctionAppDirectory)
   // This gives you access to your application settings 
   // in your local development environment
   .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true) 
   // This is what actually gets you the 
   // application settings in Azure
   .AddEnvironmentVariables() 
   .Build();
        
   string appsettingvalue = config["appsettingkey"];

  }
 }
}

Remember to add the ExecutionContext as an injection to your Azure Function.

This piece of code fetches the configuration keys and values from Environment Variables, and a local file called "local.settings.json". This file is typically added to your Visual Studio Azure Functions project when it was first created. However, if you're jumping on a project that was created by someone else, they might have .gitignore'd the configuration file (as they probably should), so you didn't get the file.

And what should your local.settings.json file look like? Something like below:

{
  "IsEncrypted": false,
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;..."
  },
  "Values": {
    "appsettingkey":  "value" 
  }
}

And with that, you should be good in Azure Functions v3.

Accessing the settings in Azure Functions Runtime Version 2

For the second generation of Azure Functions, the code to access the Application Settings is the same, but the configuration steps are a bit different. Not quite as straightforward as v1 (you'll see that further below) or superbly easy as v3 (above), but flexible for sure.

ConfigurationManager is not used like in v1. Instead, you're supposed to use ConfigurationBuilder. Check out the code example below!

// C# ConfigurationBuilder example for Azure Functions v2 runtime
using System;
using System.IO;

using Microsoft.Extensions.Configuration; // <- you'll need this

namespace YourApp
{
 public static class YourClass
 {
	
 [FunctionName("FunctionName")]
 public static async Task<IActionResult> Run(
  [HttpTrigger(
   AuthorizationLevel.Anonymous, 
   "post", 
   Route = null)] HttpRequest req,
  // You'll need this to add the local.settings.json 
  // file for local execution:
  ExecutionContext context, 
  ILogger log)
 {
  var config = new ConfigurationBuilder()
   .SetBasePath(context.FunctionAppDirectory)
   // This gives you access to your application settings
   // in your local development environment:
   .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
   // This is what actually gets you the application settings in Azure
   .AddEnvironmentVariables() 
   .Build();
				
   string appsettingvalue = config["appsettingkey"];

  }
 }
}

Just like v3. Good stuff.

However, you won't only need to add a reference to Microsoft.Extensions.Configuration and a new parameter "ExecutionContext context" to your function - see below:

using Microsoft.Extensions.Configuration;

namespace YourNamespace
{
 public static class YourClass
 {
  [FunctionName("FunctionName")]
  public static async Task RunAsync(
   [HttpTrigger(
    AuthorizationLevel.Anonymous, 
    "get", 
    "post", 
    Route = null)]HttpRequest req,
   TraceWriter log, 
   ExecutionContext context)
  {
   // omitted for clarity
  }
 }
}

You might also need to add a NuGet package for Microsoft.Extensions.Configuration - should be easy enough!

Adding Microsoft.Extensions.Configuration Nuget package

Adding Microsoft.Extensions.Configuration NuGet package

However, with v2 your configuration might not quite be done yet.

Your error might be something like this:

Error CS1061

'IConfigurationBuilder' does not contain a definition for 'AddEnvironmentVariables' and no accessible extension method 'AddEnvironmentVariables' accepting a first argument of type 'IConfigurationBuilder' could be found (are you missing a using directive or an assembly reference?)

If you get an error for .SetBasePath(), .AddJsonFile() or .AddEnvironmentVariables(), basically just add more NuGet packages until the issue is resolved 😅 Sounds confusing, but the different configuration options are now really granular - so you'll need a few packages. I have listed them below...

There are a lot of NuGet packages to help you out! Start with these:

  • SetBasePath() requires:
    • Microsoft.Extensions.Configuration.Abstractions
  • AddJsonFile() requires:
    • Microsoft.Extensions.Configuration.FileExtensions
    • Microsoft.Extensions.Configuration.Json
  • AddEnvironmentVariables() requires:
    • Microsoft.Extensions.Configuration.EnvironmentVariables and possibly
    • Microsoft.Extensions.Configuration.UserSecrets

This rather granular approach to configurations might optimize the size and performance of the resulting software package, but it does make parts of the development cycle just a bit frustrating :)

Accessing the settings in Azure Functions Runtime Version 1

The 1.x generation of Azure Functions SDK uses the very traditional ConfigurationManager for accessing the Environmental variables or Application Settings. This example below shows how you can, for example, fetch the client id, client secret, and Azure AD domain information for use later in the code:

// C# ConfigurationManager example for Azure Functions v1 runtime
var clientId = System.Configuration.ConfigurationManager.AppSettings["ClientId"];
var clientSecret = System.Configuration.ConfigurationManager.AppSettings["ClientSecret"];
var aadDomain = System.Configuration.ConfigurationManager.AppSettings["AADDomain"];

Nice and easy! ConfigurationManager is the good-old way of getting your hands on the settings. It exposes AppSettings, which is just a NameValueCollection - with a key (or "name"), you get back a string-typed value.

In a production workload, you might want to consider using Azure Key Vault instead of the app settings - but that's a topic for another article!

Accessing the settings in Azure Functions Runtime Versions 1 & 2 for .NET Core < 2.0

While you look at the model for managing the configurations in v2, and if you're not on v3 yet, you might think adding a dozen NuGet packages looks like a bit of an overkill. That's ok - if you only need to get application settings, there's a couple of shortcuts you can take!

Remember the good old GetEnvironmentVariable() ? The one we've been using since... Well, I suppose since .NET Framework 1.1!

Guess what? It still works!

So, if the only thing you need the configuration for is application settings, just run this to return value for key "ClientId":

// C# Environment Variables example for Azure Functions v1 or v2 runtime

// This works all the way up to but not including .NET Core 2.0
var clientId = Environment.GetEnvironmentVariable("ClientId");
var clientSecret = Environment.GetEnvironmentVariable("ClientSecret");
var aadDomain = Environment.GetEnvironmentVariable("AADDomain");

Interestingly enough, the GetEnvironmentVariable() doesn't seem to work in .NET Core 2.0 anymore, though.

A quick side note: In case you're not developing an Azure Function (but rather a Web App or something), you could inject the handy IConfiguration (from "Microsoft.Extensions.Configuration") parameter to the Startup method, and you henceforth you can access the application settings like this:

// C# Injected Configuration object example
// This works for .NET Core 1.x and later!

public class Startup
{
 public Startup(IConfiguration configuration)
 {
  Configuration = configuration;
 }

 public IConfiguration Configuration { get; }

 public void ConfigureServices(IServiceCollection services)
 {
  var clientId = Configuration["Values:ClientId"];

  // The rest of the implementation omitted ...
 }
}

... but for an Azure Function, you don't have it available as is. Instead, use the way shown above for v1, v2, or v3.

Where are these configuration keys stored in?

Okay - back to basics for a second. Where do these different methods get their values from? Where do you need to look at, if you're not getting what you're expecting?

For Azure Functions app settings, they're stored either locally in a configuration file, or when deployed, in the Azure (Function) App Service's application settings (Platform Features > Configuration > Application settings).

And an example of a local configuration file ("local.settings.json") containing these values is below:

The contents look something like this:

{
 "IsEncrypted": false,
 "Values": {
  "AzureWebJobsStorage": "",
  "AzureWebJobsDashboard": "",
  "ClientID": "[your value here]", // "Application ID" from Azure AD app registration
  "ClientSecret": "[your value here]",
  "AADDomain": "[your value here]"
 }
}

This example is for Azure Functions v2 or v3.

See more info

Below are a couple of great links for further reading:

Comments

Interactive comments not implemented yet. Showing legacy comments migrated from WordPress.
Kuttikrishnan P
2019-02-28 01:55:04)
Hi Antti, This is an awesome article and thanks for the detailed steps. I have tried creating an azure function V2 using ASP.net core and EF core.There I am using the Starp.cs file and inside that I am doing all my Startup activity like , setting the DBContext , Setting all the dependency . But inside this I am not able to get the context ("Execution Context") .It always returns me "null" value . The execution context i wanted to use to set the BasePath of the configuration. But the same is always null in the Startp.cs. var configuration = new ConfigurationBuilder() .SetBasePath(context.FunctionDirectory) .AddJsonFile("local.settings.json", true, reloadOnChange: true) .AddEnvironmentVariables() .Build(); So please let me know how can make the above code to work. Appreciate your Support . Regards, Kutti
2019-03-01 21:51:37
Hi Kutti! Thanks for your question. I've been thinking of writing an article about using an Entity Framework dbcontext inside an Azure function, as that's a requirement that came up for a recent POC we built. I could definitely post that some day soon! About your case especially - are you able to get values for the other application settings? If so, could you paste your code from StartUp.cs here? Oh - and are you saving the connection string as an application setting or a connection string? The method for retrieving them is slighty different! Cheers! :)
Jim Ownby
2019-04-24 09:01:34)
I know this is a bit late for this but you have a typo referencing the NuGet package "Microsoft.Extensions.Configuration.EnvironmentVariables".
2019-04-25 14:31:28
Hi Jim, Never too late to point out a factual mistake in an article! Thanks for noticing, I'm blaming lousy copy-pasting skills... :) Will fix it!
Efron
2019-06-18 01:18:22)
Hi Antti, Thank you for this great article. Environment Variables in Azure have a flat structure. How do you introduce nesting (in your local.settings.json) to those environment variables? For instance: config.Bind("MailSettings", mailSettings); you cannot define MailSettings section in environment variables. You can do this locally, but you cannot access local.settings.json on the portal. what is the solution when published accessing hierarchical configuration data?
2020-04-14 22:49:45
Hi Efron, Apologies for an awfully slow response. I've been trying to find the time to improve and partially rewrite this article (and a few others, to be quite frank!) You can't, to my knowledge, bind sections of your application settings in Azure, even though you can do that locally. You can do it for .NET Core web projects, though - perhaps that's a topic for another article right there. The hierarchy in Azure Functions only goes to predefined areas, like config["ConnectionStrings:DefaultConnection"] and config["Values:YourAppSettingsKey].
Cesar
2019-10-08 15:42:30)
I don't understand why we can't use a static method for reading configuration. What's the need for this flexibility ? An environment configuration is static by definition. Reading configuration was a trivial task and now it needs new software design in some cases. This is a another very poor .net core decision in my opinion.
2019-10-09 17:04:20
Hi Cesar, I agree, that it's not the most intuitive approach. The team has done a great job overall, but there are definitely some pain points for us devs to deal with... :)
Monsignor
2019-11-15 07:23:32)
> But there you have the handy “Microsoft.Extensions.Configuration” parameter injected to the Startup method Which Startup method? The Startup.Configure(IFunctionsHostBuilder builder) seems to have no access to configuration.
2020-04-14 22:53:30
Thanks for your comment, Monsignor! That part of the article was a quick detour to settings anywhere outside Azure Functions, and didn't apply to Azure Functions. I wrote this part of the article because I can see from analytics that there's a couple thousand or so people ending up on this page each month searching for info on how to access application settings for "normal" .NET Core projects. I tried making the article a bit more understandable. More clear now?
Thanzeel
2020-03-04 03:48:30)
i have tried accessing the nested properties in the local.host.json file but i dont understad how i can access them after i deploy to azure becouse the local.host.json is only for local developmet im using azure function v2, .netcore 2.2
2020-03-04 22:01:30
That depends on your configuration Example - this'll read "DefaultConnection" under "ConnectionStrings" node: var config = new ConfigurationBuilder() .SetBasePath(context.FunctionAppDirectory) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddEnvironmentVariables() .Build(); string connectionString = config["ConnectionStrings:DefaultConnection"];
Shyam
2021-09-17 09:27:09)
What about the section that we add in local.setting.json. It works locally but not after the deployment. Configuration.GetSection does not work. Any workaround for that. My section looks like an array of strings like "mysection" : ["One", "Two", "Three"] Any help on this is appreciated
2021-10-03 23:00:17
Hi Shyam, Can't think of a quick solution from the top of my head - I'd probably just store the configuration as a JSON object and parse it on the program start, which sounds like an easy workaround. I'd love to hear if you found an actual solution, though!