Reputation: 4201
I am using Microsoft.Extensions.Configuration
in ASP.NET Core 9.0 to access configurations from the appsettings.json
file:
public class MySettings
{
public int? Foo { get; set; }
public string[]? Bar{ get; set; }
}
appsettings.json:
{
[...]
"MySettings": {
"Foo": 42,
"Bar": [
"a",
"b",
"c"
]
}
}
I'm reading this part this way:
var mySettings = config.GetSection("MySettings").Get<MySettings>();
This works well, mySettings.Bar
is string[3] = ["a", "b", "c"]
as you'd expect.
Now I'm having trouble to distinguish between three other cases in appsettings.json
:
A:
{
[...]
"MySettings": {
"Foo": 42
}
}
B:
{
[...]
"MySettings": {
"Foo": 42,
"Bar": null
}
}
C:
{
[...]
"MySettings": {
"Foo": 42,
"Bar": []
}
}
For all three cases, mySettings.Bar
will become null
, but I'd want only A and B to become null
, and C to become string[0]
.
I have found lots of little bits and ideas from a question for Newtonsoft Json.NET but I can't seem to figure out how to cram it all into something that works with Microsoft.Extensions.Configuration
:
[]
for Bar
, like also suggested here; that alone would break A and B thoughMissingMemberHandling
; not sure Include
would lead to null
overriding a default value; and does System.Text.Json
even have anything like this?NullValueHandling
; same questions as for MissingMemberHandling
MySettings
could maybe do it if keep the default to be null
and get to take my own look at the JsonElement
when the property is parsed; I don't know where to set JsonSerializerOptions
for Microsoft.Extensions.Configuration
Bar
itself; but which? System.Text.Json
doesn't have a lot to begin withIt is crucial for me to be able to differentiate between A and C. B should preferably become null
since that's what the file says, but I could cope with that becoming string[0]
as well, too.
Upvotes: 2
Views: 138
Reputation: 23234
Appsettings are not being handled by json (de)serialization, but by the JsonConfigurationFileParser
which uses custom parsing.
This JsonConfigurationFileParser
has private built-in logic to set empty arrays to null
; see source code on GitHub.
A possible solution to achieve your goal is to inspect the MySettings
configuration section as a Dictionary<string, object>
. When applicable, adjust the value of the Bar
property on the mySettings
instance returned from below statement that you are already using.
var mySettings = config.GetSection("MySettings").Get<MySettings>();
TryGetValue
method of the dictionary will return false.Bar
. This is also a rather unexpected behavior of the JsonConfigurationFileParser
.Bar
is null
.That gives below code, which checks whether the Bar
key is present and whether the value is not an empty string. If so, either an array with values or an empty one has been configured and a possible null
value for property Bar
needs to be replaced by an empty array.
var mySettings = config.GetSection("MySettings").Get<MySettings>();
var section = config.GetRequiredSection("MySettings").Get<Dictionary<string, object>>()!;
if (section.TryGetValue("Bar", out var value)
&& value is not string
)
{
mySettings.Bar ??= [];
}
Upvotes: 2