2

In my C# (v9) .Net 6 app, I have a class with the following member variable:

private readonly List<Dictionary<ConsoleColor, ConsoleColor>> colours = new ()
{
    new Dictionary <ConsoleColor, ConsoleColor> (),
    new Dictionary <ConsoleColor, ConsoleColor> ()
};

I write it to json, in a file like this:

using System.Text.Json;
using System.Text.Json.Serialization;    

var options = new JsonSerializerOptions {
    WriteIndented = true,
    Converters = {
        new JsonStringEnumConverter (JsonNamingPolicy.CamelCase)
    }
};
string json = JsonSerializer.Serialize (this.colours, options);
using StreamWriter stream = File.CreateText (filePath);
stream.Write (json);

but when I try to read this back again as follows:

string json = File.ReadAllText (filePath);
var options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true
};
this.colours = JsonSerializer.Deserialize<List<Dictionary<ConsoleColor,ConsoleColor>>> (json,options);

I get an exception:

"The JSON value could not be converted to System.Collections.Generic.Dictionary`2[System.ConsoleColor,System.ConsoleColor]. Path: $[0].blue | LineNumber: 2 | BytePositionInLine: 18."

What am I doing wrong? The json looks good as a string - the exception occurs on the deserialisation (JsonSerializer.Deserialize). I think it might be expecting a number for the colour, but reading text instead, but I really do want my json to be human-readable (and in a pinch, editable).

The json file looks like this:

[
  {
    "blue": "gray",
    "cyan": "gray",
    "darkBlue": "darkGray",
    "darkCyan": "darkGray",
    "darkGreen": "darkGray",
    "darkMagenta": "darkGray",
    "darkRed": "darkGray",
    "darkYellow": "darkGray",
    "green": "gray",
    "magenta": "gray",
    "red": "gray",
    "yellow": "gray"
  },
  {
    "black": "black",
    "blue": "gray",
    "cyan": "gray",
    "darkBlue": "darkGray",
    "darkCyan": "darkGray",
    "darkGreen": "darkGray",
    "darkMagenta": "darkGray",
    "darkRed": "darkGray",
    "darkYellow": "darkGray",
    "green": "gray",
    "magenta": "gray",
    "red": "gray",
    "yellow": "gray"
  }
]
5
  • You’re not using a JsonStringEnumConverter when deserialising? Commented Nov 18, 2023 at 2:03
  • @stuartd, no - do I need to? Commented Nov 18, 2023 at 2:03
  • I would think so, yes. Generally converters used for serialization are also needed for deserialisation. Commented Nov 18, 2023 at 2:04
  • You do need to use JsonStringEnumConverter when deserializing. Absent that, System.Text.Json serializes and deserializes enums as integers. Commented Nov 18, 2023 at 2:14
  • See: e.g. ASP.NET MVC Core API Serialize Enums to String. Commented Nov 18, 2023 at 2:20

1 Answer 1

3

Thanks to @stuartd and @dbc - the answer is to use a JsonStringEnumConverter when deserialising too. For the code above, I just added:

Converters =
{
    new JsonStringEnumConverter (JsonNamingPolicy.CamelCase)
}

into the JsonSerializerOptions.

Sign up to request clarification or add additional context in comments.

Comments

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.