skip to Main Content

I’m trying to migrate some functionality of a legacy .NET Framework over to Azure Function Apps V4 using dotnet-isolated. I can trigger the application, however the app settings and connection strings defined in the Azure Portal are not available through ConfigurationManager. Other parts of this application are hosted on App Services and ConfigurationManager works fine there.

There’s a lot of information available about IConfiguration and local.settings.json, however that’s not what I can use. There’s a lot of code depending on ConfigurationManager.AppSettings and ConfigurationManager.ConnectionStrings, which need to keep working as-is. One example is EF6, but also other custom code.

I’ve defined the app settings and connection strings in the Azure Portal. I can see these as environment variables in the Kudu "Environment" view, like this:

  • APPSETTING_my_setting="myvalue"
  • SQLAZURECONNSTR_my_connection_string="foo=bar"

I somehow would’ve expected for this to "just work", but it doesn’t. Am I holding it wrong, or what can I do to convince ConfigurationManager to use these settings?

2

Answers


  1. The Values which are set in the local.settings.josn are available as Environment Variables.

    My .csproj file:

    <Project Sdk="Microsoft.NET.Sdk">
      <PropertyGroup>
        <TargetFramework>net7.0</TargetFramework>
        <AzureFunctionsVersion>v4</AzureFunctionsVersion>
        <OutputType>Exe</OutputType>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
      </PropertyGroup>
      <ItemGroup>
        <PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.14.1" />
        <PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.0.13" />
        <PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.10.0" />
        <PackageReference Include="Microsoft.Extensions.Configuration" Version="7.0.0" />
      </ItemGroup>
      <ItemGroup>
        <None Update="host.json">
          <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
        </None>
        <None Update="local.settings.json">
          <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
          <CopyToPublishDirectory>Never</CopyToPublishDirectory>
        </None>
      </ItemGroup>
      <ItemGroup>
        <Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
      </ItemGroup>
    </Project>
    

    We can read either by using the EnvironmentVariable or from the IConfiguration.

    Using EnvironmentVariable:

     string? my_setting = Environment.GetEnvironmentVariable("my_setting");
     string? my_connection_string = Environment.GetEnvironmentVariable("my_connection_string");
    

    My Function1.cs file:

    using System.Net;
    using Microsoft.Azure.Functions.Worker;
    using Microsoft.Azure.Functions.Worker.Http;
    using Microsoft.Extensions.Logging;
    
    namespace ConfigManager14June
    {
        public class Function1
        {
            private readonly ILogger _logger;
    
            public Function1(ILoggerFactory loggerFactory)
            {
                _logger = loggerFactory.CreateLogger<Function1>();
            }
    
            [Function("Function1")]
            public HttpResponseData Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req)
            {         
    
                var response = req.CreateResponse(HttpStatusCode.OK);
                response.Headers.Add("CustomHeader", "CustomValue");
                response.StatusCode = HttpStatusCode.OK;
    
                string? my_setting = Environment.GetEnvironmentVariable("my_setting");
                string? my_connection_string = Environment.GetEnvironmentVariable("my_connection_string");
    
                string responseBody = "my_setting - " + my_setting + " , my_connection_string - " + my_connection_string;
    
                response.WriteString(responseBody);
                return response;
            }
        }
    }
    

    Using IConfiguration:

    private readonly IConfiguration _configuration;
    public Function1(IConfiguration myconfig)
    {    
        _configuration = myconfig; ;
    }
    string my_setting = _configuration["my_setting"];
    string my_connection_string = _configuration["my_connection_string"];
    

    OR

    If set under ConnectionString

      "ConnectionStrings": {
        "my_connection_string1": "foo=bar"
      }
    

    then read it as,

    string myConnectionString = _configuration.GetConnectionString("my_connection_string1");
    

    Output:

    enter image description here

    Login or Signup to reply.
  2. ConfigurationManager has never been driven by environment variables, and supports the .config XML configuration pattern. You still have that in App Service, in that it has a filesystem where those files can be placed in the relative location that (ASP.)NET expects, but it has no relationship to the App Service configuration collection. I suppose if you are familiar with IIS on-premises you might imagine that the configuration UI would be a view onto this XML configuration file, but that isn’t the case anymore, App Service configuration is distinct and is expressed to the application as environment variables.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search