KafkaFlow serialises like this
{
"actions": {
"$type": "Full.ActionTypeName, supplying-assembly-name",
"$values": [
{
"propname": "propvalue" //properties of ActionTypeName instance
}
]
},
"resources": {
"$type": "Full.ResourceTypeName, supplying-assembly-name",
"$values": [
{
"propname": "propvalue" //properties of ResourceTypeName instance
}
]
}
}
With the following classes
using System.Text.Json;
using System.Text.Json.Serialization;
public class FlowMessage
{
public FlowType Actions { get; set; }
public FlowType Resources { get; set; }
}
public class FlowType
{
[JsonPropertyName("$type")]
public string TypeDescriptor { get; set; }
[JsonPropertyName("$values")]
public JsonElement[] Values { get; set; }
public string TypeName() => TypeDescriptor.Split(",")[0];
public Type Type() => System.Type.GetType(TypeName());
}
I can get this to parse.
var stream = File.Open("sample.json", FileMode.Open, FileAccess.Read);
JsonSerializerOptions seropt = new()
{
PropertyNameCaseInsensitive = true,
Converters = { new JsonStringEnumConverter() }
};
var foo = JsonSerializer.Deserialize(stream, typeof(FlowMessage), seropt);
This "FlowType" notation is used recursively to represent object graphs. According to the JsonSerializer
documentation it is possible to associate a JsonConverter with a type. What I want to do is apply this somehow so that instead of the pair of nodes $type
and $values
the serialiser returns an array of objects of appropriate type.
It seems like I need to use the factory pattern converter described on that page, but I need a value from inside the FlowType
instance to determine the target type for the converter that the factory will produce. So I need to parse it first as a FlowType
and then again using the converter. It's really not obvious how to go about this.
Surely someone has built a deserialiser of this sort. I look forward to your advice on how to deal with this.
It appears you can trivially clone the reader for the purpose of read-ahead as described elsewhere in the same document. But I'm still pretty wobbly so if someone knows what they're doing with this I wouldn't object to being led by the nose.
It appears this format is supported in both directions by Newtonsoft.Json
if you specify serialisation options as follows.
JsonSerializerSettings _options = new()
{
TypeNameHandling = TypeNameHandling.Auto,
};
I'd rather not run two serialisers so if anyone can figure out how to handle it using System.Text.Json
I would accept that as the correct answer.