In this blog I'll show you why to avoid arrays in appsettings.json
when deploying to Azure.
Strange Behavior
When deploying a Web App to Azure you need to override your configuration. I had this in my appsettings.json
file:
appsettings.json
{
...
"CORS": {
"AllowedDomains": [ "https://localhost:44306" ]
}
}
And I used the Azure portal to override the configuration as follows:
To my surprise the deployed application was still using localhost
instead of the production URL.
Investigation
I set up a little test with the following C# code:
ViewBag.AllowedDomainsAsString = configuration["CORS:AllowedDomains"]; // read as string
var strings = configuration.GetSection("CORS:AllowedDomains").Get<string[]>();
ViewBag.AllowedDomainsAsStringArray = string.Join(',',strings);
This gave me the following result:
It turns out that reading configuration as a string[]
would always give me the values from appsettings.json
.
This makes sense when you think about it. The way Azure overrides configuration is by setting environment variables. And environment variables have to be strings, not arrays. I could clearly see my mistake when using the 'Advanced Editor' in Azure.
Advanced Editor
[
{
"name": "CORS:AllowedDomains",
"value": "[\"https://lander.edu\"]",
"slotSetting": false
}
]
Removing the double quotes would lead to an invalid file. So, no luck there.
Solution
Three solutions came to mind:
- Overriding
appsettings.json
in the build pipeline
- Using Azure App Configuration (which is a separate service in Azure)
- Using a string and separating the URLs using a specific character
appsettings.json
{
...
"CORS": {
"AllowedDomains": "https://localhost:44306;https://localhost:44307"
}
}
I ended up doing the last thing since it was a minor change.
Conclusion
Be wary about using arrays in your configuration. The problem does not occur with objects, or non-string primitives like numbers. For objects you can simply use the :
or __
separator. And non-string primitives simply convert properly from a string.