Search code examples
c#json.netserializationstatic-classes

Convert JsonElement to property type


When implementing serialization of a static class, I encountered a problem with type conversion. My code:

var properties = type.GetProperties(BindingFlags.Static | BindingFlags.Public);
var dictionary = JsonSerializer.Deserialize<Dictionary<string, object>>(File.ReadAllText(filePath));
foreach (var property in properties) {
    property.SetValue(null, dictionary[property.Name]);
}

An exception occurs on startup:

System.ArgumentException: 'Object of type 'System.Text.Json.JsonElement' cannot be converted to type 'System.String'.'

How do I write values ​​from a deserialize dictionary?

I tried to iterate through the dictionary values ​​and convert them to the required type.

foreach (var property in properties) {
    var value = (JsonElement)dictionary[property.Name];
    var json = value.GetRawText();
    JsonSerializer.Deserialize<object>(json);
}

Solution

  • Without diving into why you want to do that (arguably you should not), from pure technical point of view you can use the underlying type for such deserialization - JsonElement and use it's Deserialize method accepting instance of Type. For example:

    var dictionary = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(File.ReadAllText(filePath));
    foreach (var property in properties)
    {
        property.SetValue(null, dictionary[property.Name].Deserialize(property.PropertyType));
    }
    

    Or via JsonNode API, basically doing the same:

    var dictionary = JsonNode.Parse(File.ReadAllText(filePath));
    foreach (var property in properties)
    {
        property.SetValue(null, dictionary[property.Name].Deserialize(property.PropertyType));
    }
    

    But personally I would deserialize to some non-static type and then map the properties (also arguably nowadays a static classes needed not that often and this is a question if you should use any at all).