3

I know i could add all my environment vars under the values {} section of local.settings.json. I am however trying to keep a tidy home and would like if I could do something like this.

local.settings.json

   {
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"AzureWebJobsDashboard": "",
"Hello": "world"
 },
"ClientConfiguration": {
    "this": "that",
    "SubscriberEndpoint": "",
    "Username": "",
    "Password": "",
    "ObjectEndpoint": ""
 }
}

in my code i have

 var config = JsonConvert.DeserializeObject<myConnectionObject> (Environment.GetEnvironmentVariable("ClientConfiguration"));

No matter what I do I cannot get this to work. Why can't I at least get the contents of ClientConfiguration? Just keeps coming back null.

IF I add ClientConfiguration {} to the values like

..."Values" : { ... 
"Hello":"world",
"ClientCOnfiguration" : {above}
}

I end up with an error saying azurewebjobsstorage can't be found and 'func settings list' is just empty

Jerry Liu
  • 17,282
  • 4
  • 40
  • 61
macm
  • 544
  • 7
  • 21

3 Answers3

5

For local.settings.json, only Values section can be imported into Environment variables.(If your function is v2, ConnectionStrings section is also there in Environment variables). So you see null as the result.

What's more, Values section is a Dictionary<string, string> which means value can't be in other format except string. Hence your ClientCOnfiguration inside results in error .

Since you want to reorganize those settings, serializing ClientConfiguraiton to store it in Values seems not a good option. We may need simply reading and parsing Json file.

Add ExecutionContext context in your function method signature and try code below.

var reader = new StreamReader(context.FunctionAppDirectory+"/local.settings.json");
var myJson = reader.ReadToEnd();
dynamic config =  JsonConvert.DeserializeObject(myJson);
var clientConfiguration = config.ClientConfiguration as JObject;
myConnectionObject mco = clientConfiguration.ToObject<myConnectionObject>();

If your function is v2, there's another way with ConfigurationBuilder.

var config = new ConfigurationBuilder()
    .SetBasePath(context.FunctionAppDirectory)
    .AddJsonFile("local.settings.json", optional: false, reloadOnChange: true)
    .AddEnvironmentVariables()
    .Build();
var mco = new myConnectionObject();
config.GetSection("ClientConfiguration").Bind(mco);

Note that local.settings.json is for local dev, it won't be uploaded to Azure by default. Need to remove <CopyToPublishDirectory>Never</CopyToPublishDirectory> in functionname.csproj.

Jerry Liu
  • 17,282
  • 4
  • 40
  • 61
  • Thanks for your assistance. I was hoping to avoid all that, especially readinging the settings.json from a reader since it won't work in azure correctly. Anyway. .I guess i need to just accept this is the design. – macm Oct 17 '18 at 14:21
  • 1
    Does this work when the code is deployed to a Function App? Then you don't have a local.settings.json. – Oliver Nilsen Oct 11 '22 at 10:51
1

If you don't want to instantiate a new ConfigurationBuilder, you can simply format your settings in another way. Your local.settings.json file would look like this:

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "AzureWebJobsDashboard": "",
    "Hello": "world",
    "ClientConfiguration__this": "that",
    "ClientConfiguration__SubscriberEndpoint": "........",
    "ClientConfiguration__Username": "........",
    .....
 }
}

Please note that the double underscores are important, as it instructs the environment variables reader to take this as a property of the complex object ClientConfiguration. Your custom properties have to be located inside the Values object, otherwise they won't be injected as environment variables.

Loul G.
  • 997
  • 13
  • 27
  • Just a heads up that the [documentation](https://learn.microsoft.com/en-us/azure/azure-functions/functions-run-local#local-settings-file) explicitly states that setting names should not contain double underscores (`__`) or colons (`:`), so I wouldn't rely on this if it currently works. – Damiene Jul 06 '19 at 20:18
  • 2
    @Damiene: The documentation says that the settings should not contain those chars because they are used by the runtime. That's exactly the purpose. Actually you should'nt used those chars if you don't want to see your setting treated as an object__property. As a side note, this convention can also be used in the csproj properties, in the environment variables. – Loul G. Jul 08 '19 at 15:55
  • Adding a little bit more information. I create user-secrets which is a JSON where the name key uses ":". Those properties load into the configuration. So, following the same format, I was able to add the values I need. I could create a JSON object since the documentation says do not use arrays or objects. – Richard Valdivieso Aug 29 '22 at 19:40
0

AS far as I know, Values collection is expected to be a Dictionary, if it contains any non-string values, it can cause Azure function can not read values from local.settings.json. For more details, please refer to the blog

Jim Xu
  • 21,610
  • 2
  • 19
  • 39