Deserializing 3rd-party JSON into a base (abstract) class in System.Text.Json
What is the most performant way to accomplish this? The most common solution to this problem (in Json.NET anyway?) is to implement a custom JsonConverter which first converts the object to a JObject, then checks for a discriminator property (or properties) before deciding how to deserialize/convert the JObject. This works, clearly, but I have doubts/concerns about its performance at scale as far as speed is concerned. I really, REALLY would like to avoid anything involving shoving every single possible field from the derived classes into one massive model abomination. Changing the JSON is out of the question as this is third-party data coming in from a websocket.
The data is pretty much
followed by SomeType-specific event fields.
type
is guaranteed to exist. Could I use this field as a discriminator somehow?
My concern is that solutions involving JsonConverter delve into solutions almost always including a switch statement on the discriminator property. My issue is that this type
field can have...almost 35 values, and I'm sure even more as the events this websocket can send to me will expand with time as well. The idea of a 35-case switch statement doesn't sit well with me2 Replies
And no, I haven't actually tried benchmarking the Json.NET approach (or whatever the STJ equivalent would be), this is obviously just a gut feeling, so if I'm totally wrong about how slow doing it that way is, I'm open to considering it anyways.
I have been enlightened as to another way to accomplish this, and I can confirm it works:
I'm actually OK with this, but one issue...Any idea why
Type
never seems to be deserialized correctly? No matter what the model type, Type
is always Error
, which is the default (first) value defined in the enum. This is the case even when I've confirmed that my serializer settings are using a JsonStringEnumConverter
. Do I need to do something special for it to work? it's weird that it's deserializing to the correct type, meaning SOMETHING is picking up the right value, but then it's not getting deserialized correctly.Not sure it makes it better or more performant (it's probably worse?), but it saved me a lot of headaches once.
You can actually transform the xml using xslt at runtime and replace the original node name with the value of your discriminator. Then you deserialize it all like normal nodes.