I have two messages like so:
string test1 = @"{ ""coords"": { x: 1, y: 2, z: 3 }, ""w"": 4, ""success"": true}";
string test2 = @"{ ""coords"": { x: 1, y: 2, z: 3 }, ""success"": true}";
Given the following classes that I want to deserialize into:
public struct Coordinate
{
public int x { get; set; }
public int y { get; set; }
public int z { get; set; }
public int w { get; set; }
}
public class MessageBody
{
[JsonConverter(typeof(JsonCoordinateConverter))]
public Coordinate Coords;
public bool Success { get; set; }
}}
Is it possible to write the JsonCoordinateConverter
such that it is able to read the w
property, which is outside of the context of coords
object?
I tried the following:
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
Coordinate coords = new Coordinate();
JObject coordObject = JObject.Load(reader);
// move to the next token
reader.Read();
if (reader.Path == "w")
{
coords.w = reader.ReadAsInt32().Value;
}
else
{
// for test2, the token here is success,
// how do I rewind for the regular deserializer to read it?
reader.Skip();
}
coords.x = coordObject["x"].Value<int>();
coords.y = coordObject["y"].Value<int>();
coords.z = coordObject["z"].Value<int>();
return coords;
}
With this approach though, I'm reading over the success
property if w
is not in the original message, and the regular deserializer does not pick up the success
value. So I'd need to somehow peek to check whether w
is there or not, or rewind when I don't find it, but can't find a way to do either.
Note: this is a very simplified representation of the issue, the real message and objects are bigger, and the regular deserializer works fine for them, so I'd like to avoid writing custom code for everything and keep it to coords
+w
only, if at all possible.
Working demo code gist, second assert fails of course.