Home > Software engineering >  .Net 6 function app not getting values from Azure application settings
.Net 6 function app not getting values from Azure application settings

Time:06-02

I created a new .net 6 in-process function app using Visual Studio 2022. The function app contains three (3) timer functions. I have a custom settings class that is populated from configuration settings. The function app runs properly on my local development machine from Visual Studio.

The problems occurs after it has been deployed to Azure. The Dependency Injection fails in the Startup class because the custom settings class is not being populated properly from the app function application settings.

Here is the settings class:

    public class Settings
    {
        public ConnectionStrings ConnectionStrings { get; set; }
        public TwilioSettings TwilioSettings { get; set; }
    }

    public class TwilioSettings
    {
        public string AccountSid { get; set; }
        public string AuthToken { get; set; }
        public string From { get; set; }
    }

    public class ConnectionStrings
    {
        public string ZZZZZZZ { get; set; }
    } 

I have a local.settings.json file with the necessary key/value pairs for the custom settings:

{
  "IsEncrypted": false,
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet"
  },
  "AzureWebJobsStorage": "UseDevelopmentStorage=true",
  "FUNCTIONS_WORKER_RUNTIME": "dotnet",
  "ConnectionStrings": {
    "ZZZZZZZ": "xxxxxxxxxxxxxxxxxxxxxxxx"
  },
  "TwilioSettings": {
    "AccountSid": "xxxxxxxxxxxxxxxx",
    "AuthToken": "xxxxxxxxxxxxxxxxx",
    "From": "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
  }
}

In the Startup.cs, I have the following configuration binding:

        public override void Configure(IFunctionsHostBuilder builder)
        {
            var settings = new Settings();
            var basePath = $"{Directory.GetParent(Assembly.GetExecutingAssembly().Location).FullName}\\";
            var jsonPath = $"{basePath.Substring(0, basePath.LastIndexOf('\\'))}\\local.settings.json";
            
            var config = new ConfigurationBuilder()
                        .SetBasePath(basePath)
                        .AddJsonFile(jsonPath, true)
                        .AddEnvironmentVariables()
                        .Build();
            config.Bind(settings);

            builder.Services.AddSingleton(settings);
            builder.Services.AddSingleton(settings.TwilioSettings);
            var cs = settings.ConnectionStrings.ZZZZZ;
            builder.Services.AddDbContextFactory<JTMContext>(opt => opt.UseSqlServer(cs));
            builder.Services.AddDbContext<JTMContext>(opt => opt.UseSqlServer(cs));

        }

I created the function app resource in Azure, prior to deploying from Visual Studio. I added the necessary key/value pairs to the Application Settings and Connection Strings:

Azure Function App Configuration

Once I publish the function app from Visual Studio, everything looks fine until one of the timer functions get triggered. Then I see the following error:

Microsoft.Extensions.DependencyInjection.Abstractions: Value cannot be null. (Parameter 'implementationInstance').

This is failing in the Startup.cs when trying to register the custom Settings in the Configure() method:

        public override void Configure(IFunctionsHostBuilder builder)
        {
            ...
 
            config.Bind(settings);

            builder.Services.AddSingleton(settings);
            builder.Services.AddSingleton(settings.TwilioSettings);

            ...
        }

It appears that the instantiated IConfigurationRoot object, config, does not have the Azure Application Settings.

What am I missing in my Startup.cs so that the Application Settings in Azure will be fed into the IConfigurationRoot?

CodePudding user response:

Did you try in the format TwilioSetting:From ?

From https://docs.microsoft.com/en-us/azure/app-service/configure-common?tabs=portal

App setting names can't contain periods (.). If an app setting contains a period, the period is replaced with an underscore in the container.

In a default Linux app service or a custom Linux container, any nested JSON key structure in the app setting name like ApplicationInsights:InstrumentationKey needs to be configured in App Service as ApplicationInsights__InstrumentationKey for the key name. In other words, any : should be replaced by __ (double underscore).

  • Related