Empty array in YAML is emitted as null
I noticed that if define a YAML configuration with a property that is set to an empty array ([]), then when I ultimately call IConfiguration.Bind to bind the config data to a class, that property is deserialized as null.
It is possible to work around this issue, by either changing the YAML to use [null] or setting up the property in the class to convert null values to an empty collection in the setter. However, I would expect that an explicitly defined empty array would be emitted as an empty collection (list, array, etc), rather than null.
For example, if I have the following YAML config and class:
# appsettings.yml
MyApp:
SomeList: []
public class MyAppConfig
{
public List<string> SomeList {get; set;}
}
And then bind it using something like this, then the resulting value of SomeList will be null, rather than an empty list
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddYamlFile("appsettings.yml", optional: false);
WebApplication app = builder.Build();
var config = new MyAppConfig();
app.Configuration.Bind("MyApp", config);
If I change the definition of SomeList to be SomeList: [null], then it will be emitted/bound as an empty list.
This feels like a bug, but it's more of an inconvenience than anything, since it can be worked around.
Interesting 🤔 I wonder if this is an issue in the yaml parser, or if this is "expected" behaviour, similar to the JSON providers etc 🤔
FWIW, as an I example I used the YamlDotNet APIs directly to deserialize the same block of YAML from my original post, and it did deserialize to an empty list, rather than null. The code was similar to the following...
var yaml = @"
MyApp:
SomeList: []";
var config = new Deserializer().Deserialize<MyAppConfig>(yaml);
I took a peek at the source for the this library, and how it's parsing the YAML. While I can't claim that I completely wrapped my head around it, it looks like this library's parser is trying to visit each node of each YAML document, and parse each node individually. I would imagine there's something in the logic there about how YAML lists/collections are handled, and that empty lists may just be skipped over during parsing, rather than being deserialized to an empty list/array/etc.
Unfortunately, I don't have the time at this very moment to look at it and possibly submit a PR, but perhaps it's something I can look at down the road. For now, I can live with the workaround of creating a list in the YAML with a single null element
So I just did a test with the JsonProvider, and interestingly this has the exact same behaviour 🤔 Sure enough, I found this exact issue in the .NET repo: https://github.com/aspnet/Configuration/issues/788
tl;dr; this is the expected behaviour, it's a limitation of the configuration binder unfortunately, so I'm not sure there's anything else I can do i'm afraid 🙁 🤷♂️