I’m facing issues in reading Nested configuration values from local.settings.json in my Azure Function(v6) and the values always seem to be coming as null. Below are my code snippets:
local.settings.json:
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "UseDevelopmentStorage=true",
"FUNCTIONS_WORKER_RUNTIME": "dotnet",
"EndpointDetails": {
"GetAllTaskDetails": {
"Url": "https://localhost:7000/api/Task/GetAllTaskDetails",
"Method": "GET",
"NotificationRecipients": "[email protected]"
},
"GetTaskDetails": {
"Url": "https://localhost:7000/api/Task/GetTaskDetails",
"Method": "GET",
"NotificationRecipients": "[email protected]"
}
}
}
}
Startup.cs:
using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
[assembly: FunctionsStartup(typeof(HealthChecker.Startup))]
namespace HealthChecker
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
// Getting the IConfiguration instance
var configuration = builder.GetContext().Configuration;
// Registering health checks
builder.Services.AddHealthChecks();
// Calling the method that defines health checks
HealthCheckDefinitions.ConfigureHealthChecks(builder.Services.AddHealthChecks(), configuration);
}
}
}
HealthCheckDefinitions.cs:
public static class HealthCheckDefinitions
{
private static Dictionary<string, List<string>> endpointDetails = new Dictionary<string, List<string>>();
public static void ConfigureHealthChecks(IHealthChecksBuilder builder, IConfiguration configuration){
private static IConfigurationSection endpointDetailsListConfig;
private static string getAllTaskDetails;
private static string getTaskDetails;
List<string> endpoints = new List<string>();
InitializeConfigValues(configuration);
endpoints.AddRange(new List<string>
{
getAllTaskDetails,
getTaskDetails
});
foreach (var endpoint in endpoints)
{
var endpointDetailsConfig
= endpointDetailsListConfig.GetSection(endpoint);
GetEndpointDetails(endpointDetailsConfig, endpoint);
foreach (var endpointDetail in endpointDetails)
{
builder.AddCheck(endpointDetail.Key, () =>
{
// lines of code
// .....
});
}
}
}
private static void InitializeConfigValues(IConfiguration configuration)
{
endpointDetailsListConfig = configuration.GetSection("EndpointDetails");
getAllTaskDetails = endpointDetailsListConfig.GetSection("GetAllTaskDetails").Key;
getTaskDetails = endpointDetailsListConfig.GetSection("GetTaskDetails").Key;
}
private static void GetEndpointDetails(IConfigurationSection endpointDetailsConfig, string endpoint)
{
if (!string.IsNullOrEmpty(endpointDetailsConfig["Url"]) && !string.IsNullOrEmpty(endpointDetailsConfig["Method"])
&& !string.IsNullOrEmpty(endpointDetailsConfig["NotificationRecipients"]))
{
endpointDetails.Add(endpoint, new List<string>
{
endpointDetailsConfig["Url"],
endpointDetailsConfig["Method"],
endpointDetailsConfig["NotificationRecipients"]
});
}
}
}
The values of the following are always null. Where am I going wrong here?
endpointDetailsConfig["Url"],
endpointDetailsConfig["Method"],
endpointDetailsConfig["NotificationRecipients"]
2
Answers
So, after spending a day breaking my head on this issue, I finally came to the solution thanks to this post which was an eye-opener for me.
Basically you should not add nested configuration in your local.settings.json file, it creates all sorts of other issues(see below issue) when you do so. Hence, I moved my nested configuration into another file like so:
Configuration.json:
And my
Startup.cs
class after necessary changes:And that's pretty much it. You can access these values easily wherever you want to, viz:
HealthCheckDefinitions.cs
Edit:
One more thing, please make sure that
CopyToOutputDirectory
is correctly set. Refer this if required. Below is my.csproj
file:I tried to give all the steps that I followed to fix this issue, hope it helps!
In your
local.settings.json
file,"GetAllTaskDetails"
and"GetTaskDetails"
exist here:I.e. at these paths:
By setting
, you try to target a section that is not at the config root level. Hence, the return value of
GetSection()
should not be an actual configuration section.As per the
.GetSection()
documentation:Side note:
To verify whether a section (or value) exists or not, call
.Exists()
on.GetSection()
‘s return value.If you rather target
"Values:EndpointDetails"
, you should be able to traverse the tree correctly from there: