I have a json string that I need to deserialize (in a WPF app, using System.Net.Json). A subobject (node) in the tree contains a variable number of propertiers/nodes with variable names. A "minimal" sample looks like this:
"intervals": [{ "timestamp": 1677477728, "123456": { "subintervals": [{ "max": "56.7", "label": "Leq" }, { "max": "58.1", "label": "Lmax" } ] } }, { "timestamp": 1677477730, "54321": { "subintervals": [{ "value": "58.5", "label": "Leq" }, { "value": "59.5", "label": "Lmax" } ] }, "56789": { "subintervals": [{ "value": "78.2", "label": "Lmax" }, { "value": "74.3", "label": "Leq" } ] } } ]
I.e. a an array "intervals" with a "timestamp" and a varying number of objects/nodes that has a number-string as key.
With the following
public class IntervalMeta
{
public long? Timestamp { get; set; }
[JsonExtensionData]
public Dictionary<string, JsonElement>? MeasurementPoints { get; set; } = new();
}
that gives a dictionary with JsonElements that I can step through and look for the desired properties. It would though be nice with a
public Dictionary<string, SubInterval[]>? MeasurementPoints { get; set; } = new();
where SubInterval
:
public class SubInterval
{
public string? Max { get; set; }
public string? Label { get; set; }
}
I am hoping and trying to make a custom JsonConverter that I could use but there are a number of issues that I don't know how to handle: Issue 0: how do I get it to use the custom JsonConverter?
My try for a converter:
public class MeasurementPointDictionaryJsonConverter : JsonConverter<Dictionary<string, SubInterval>>
{
public override Dictionary<string, SubInterval[]>? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var dict = new Dictionary<string, SubInterval[]>();
// Issue 3: How do loop over the contents in the Interval node (containing 0 or more SubIntervals)
while (reader.Read())
{
// Issue 1: How do I read the key?
var measurementPointId = reader.GetString();
// Issue 2: How do I deserialize the node to a SubInterval?
string value = reader.GetString();
var intervals = JsonSerializer.Deserialize<SubInterval[]>(value, options);
dict.Add(measurementPointId ?? "", intervals ?? new());
}
return dict;
}
public override void Write(Utf8JsonWriter writer, Dictionary<string, SubInterval[]> value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
}
I have tried just decorating the MeasurementPoints
with:
[JsonConverter(typeof(MeasurementPointDictionaryJsonConverter))]
public Dictionary<string, SubInterval[]>? MeasurementPoints { get; set; } = new();
but that just result in MeasurementPoints == null
. Adding the JsonExtensionData
attribute:
[JsonExtensionData]
[JsonConverter(typeof(MeasurementPointDictionaryJsonConverter))]
public Dictionary<string, SubInterval[]>? MeasurementPoints { get; set; } = new();
Throws an error when trying to deserialize (seems that the JsonExtensionData
can only handle Dictionary<string, JsonElement> or Dictionary<string,object>).