0

I am trying to put a list of enums into appsettings.json that will be iterated through at one point in the code. The problem is that if I put a null value into the list in the json file, it does not populate a null value into the list when the Settings are loaded from the file.

minimum code example:

using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;

class Program
{
    static void Main(string[] args)
    {
        var builder = new ConfigurationBuilder().
            AddJsonFile($"appsettings.json");

        var config = builder.Build();
        
        var test = config.GetRequiredSection("Settings").Get<Settings>();
        test.EnumList.Add(null);
    }
}

class Settings
{
    public enum EnumValues
    {
        Value1,
        Value2
    }
    public List<EnumValues?> EnumList { get; set; }
}

json file:

{
    "Settings": {
        "EnumList" :  [null, "Value1"]
    }
}

The test.EnumList.Add(null) will predictably and correctly add a null to the list, however, there will be no null in the list before that line, despite being in the json file. I would like to actually be able to put a null in the json file and have it show up in list.

How can I do this? I've hunted for a bit and I've come up with nothing.

4
  • Is there a way that you are using JsonOptions in your startup class? Are you using Newtonsoft? Commented Jul 8, 2022 at 21:40
  • Use "null" instead of null Commented Jul 9, 2022 at 14:44
  • Unfortunately, putting quotes around it does not work. I'm able to set other properties, not in lists, to null using just null. Commented Jul 12, 2022 at 14:51
  • Should have been more clear, Pablo, that I am using Microsoft.Extensions.Configuration. Commented Jul 12, 2022 at 14:53

1 Answer 1

2
+50

Retrieving that EnumList as a list of strings, shows that that null value is present, but has been stored as an empty string.

var strings = config.GetRequiredSection("Settings:EnumList").Get<List<string>>();

enter image description here

It looks like that null value gets lost when making that Get<Settings>() call.

The source code of the ConfigurationBinder at GitHub shows that an empty string or null value gets skipped for a generic nullable type - here List<Settings.EnumValues?>.

if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
    if (string.IsNullOrEmpty(value))
    {
        return true;
    }
    return TryConvertValue(Nullable.GetUnderlyingType(type)!, value, path, out result, out error);
}    

To get arround that, declare that EnumList property as an EnumValues?[] array.

public class Settings
{
    public enum EnumValues
    {
        Value1,
        Value2
    }

    public EnumValues?[] EnumList { get; set; }
}

Now the parsed Settings will contain that null value - see image.

var test = config.GetRequiredSection("Settings").Get<Settings>();

enter image description here


With this array in place, you'll have to find an other way to add an item to it, e.g. something like below.

test.EnumList = test.EnumList
    .Concat(new Settings.EnumValues?[] 
    { 
        null // Or other value
    }).ToArray();
Sign up to request clarification or add additional context in comments.

1 Comment

Excellent. Thank you so much. This is a static value that is set only at start up, I actually encapsulate it so it can't be changed, so adding things to it is not necessary. I only did that to test that I could actually add a null to the list.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.