9

I've been toying around with Json.NET and I'm liking it a lot. However, I've run into a problem when deserializing objects with value-type members. For example, consider this code:

public struct Vector
{
    public float X;
    public float Y;
    public float Z;

    public override string ToString()
    {
        return string.Format("({0},{1},{2})", X, Y, Z);
    }
}

public class Object
{
    public Vector Position;
}

class Program
{
    static void Main(string[] args)
    {
        var obj = new Object();
        obj.Position = new Vector { X = 1, Y = 2, Z = 3 };

        var str = JsonConvert.SerializeObject(obj);

        Console.WriteLine(str); // {"Position":{"X":1.0,"Y":2.0,"Z":3.0}}

        obj = JsonConvert.DeserializeObject<Object>(str);

        Console.WriteLine(obj.Position); // (0,0,0)

        Console.ReadKey(true);
    }
}

The position is serialized correctly, but it is not recovered during deserialization. Interestingly, the following code works as expected.

class Program
{
    static void Main(string[] args)
    {
        var vec = new Vector { X = 1, Y = 2, Z = 3 };

        var str = JsonConvert.SerializeObject(vec);

        Console.WriteLine(str); // {"X":1.0,"Y":2.0,"Z":3.0}

        vec = JsonConvert.DeserializeObject<Vector>(str);

        Console.WriteLine(vec); // (1,2,3)

        Console.ReadKey(true);
    }
}

As you can see, the vector is getting properly serialized/deserialized by itself. Is there an easy solution for the first scenario, or do I have to create something along the lines of a custom converter?

kloffy
  • 2,928
  • 2
  • 25
  • 34
  • 2
    Defining a class named `Object` is asking for trouble. – JaredPar Sep 30 '10 at 22:37
  • 1
    I agree, but I can safely say that it's not the source of the problem here. – kloffy Sep 30 '10 at 22:49
  • possible duplicate of [Why can I not deserialize this custom struct using Json.Net?](http://stackoverflow.com/questions/24726273/why-can-i-not-deserialize-this-custom-struct-using-json-net) – Oxoron Jul 08 '15 at 14:13

1 Answers1

9

You have two options.

  1. Change the Vector struct to a class
  2. Or Change:

    obj = JsonConvert.DeserializeObject<Object>(str);
    

    to

    obj = JsonConvert.DeserializeObject<Object>(str, new JsonSerializerSettings{ ObjectCreationHandling = ObjectCreationHandling.Replace});
    
Matthew Manela
  • 16,572
  • 3
  • 64
  • 66
  • The vector struct is provided by a library, so the first suggestion is not an option, but the second one worked. I wonder how much work it would take to make Json.NET aware of value-types and do whatever `ObjectCreationHandling.Replace` does by default on them. (Also, `PreserveReferencesHandling.All` doesn't make much sense for value-types either, so there is not need for giving them "$id"s.) – kloffy Oct 01 '10 at 12:26