1

I have a custom JsonConverter where I need to alter the default serialization and deserialization for certain properties. Looking at the deserialization:

I am overriding the ReadJson method like so:

while (reader.Read()) { if (reader.TokenType == JsonToken.PropertyName) { var propertyName = reader.Value.ToString(); if (reader.Read()) { ... 

I can then check the TokenType and if appropriate, do my custom work. This works fine for most types but if I have a property that is Enumerable and has been serialized as a JsonArray then I would like to use the default implementation for that property before continuing with my custom stuff.

How do I do this?

1 Answer 1

1

When the reader is positioned at a value, you can call JsonSerializer.Deserialize(), JToken.Load(), JArray.Load() or JObject.Load() to deserialize or load that value. Generally I prefer doing that to making manual "atomic" reads, because it ensures that nesting is handled correctly and leaves the reader correctly positioned for the next item in the JSON stream. Calling JsonSerializer.Deserialize with the appropriate type when positioned on a property value gives you the default implementation of deserialization for that property.

In fact, a simple way to write a ReadJson method is to load the entire contents of the object into a JObject, then iterate through the properties:

 var obj = JObject.Load(reader); foreach (var property in obj.Properties()) { switch (property.Name) { case "Data2": { // For example myClass.Data2 = obj.ToObject<List<double>>(serializer); } break; // More cases as necessary default: Debug.WriteLine("Unknown property " + property); break; } } 

If for whatever reason you don't want to do that, you can read property-by-property and deserialize or load individual values:

 while (reader.Read() && reader.TokenType != JsonToken.EndObject) { if (reader.TokenType == JsonToken.PropertyName) { var propertyName = reader.Value.ToString(); if (reader.Read()) { switch (propertyName) { case "Data1": { // Expecting a double value. if (reader.TokenType == JsonToken.Integer || reader.TokenType == JsonToken.Float) myClass.Data1 = Convert.ToDouble(reader.Value); else { // Unknown value, skip or throw an exception JToken.Load(reader); } } break; case "Data2": { // For example myClass.Data2 = serializer.Deserialize<List<double>>(reader); } break; case "Data3": { // Expecting a string value. myClass.Data3 = JToken.Load(reader).ToString(); } break; default: { // Unknown property, skip or throw an exception var unknownValue = JToken.Load(reader); Debug.WriteLine(string.Format("Uknown property \"{0}\" with value: {1}", propertyName, unknownValue)); } break; } } } } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.