2010-09-30 21 views
9

He estado jugando con Json.NET y me está gustando mucho. Sin embargo, me he encontrado con un problema al deserializar objetos con miembros de tipo valor. Por ejemplo, considere este código:Json.NET - ¿Los miembros de Value-Type no se deserializan?

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); 
    } 
} 

La posición se serializa correctamente, pero no se recupera durante la deserialización. Curiosamente, el siguiente código funciona como se esperaba.

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); 
    } 
} 

Como puede ver, el vector está siendo serializado/deserializado adecuadamente por sí mismo. ¿Existe una solución fácil para el primer escenario, o tengo que crear algo similar a un convertidor personalizado?

+2

La definición de una clase llamada 'Object' es buscar problemas. – JaredPar

+1

Estoy de acuerdo, pero puedo decir con seguridad que este no es el origen del problema. – kloffy

+0

posible duplicado de [¿Por qué no puedo deserializar esta estructura personalizada usando Json.Net?](http://stackoverflow.com/questions/24726273/why-can-i-not-deserialize-this-custom-struct-using- json-net) – Oxoron

Respuesta

9

Tiene dos opciones.

  1. Cambiar la estructura vectorial a una clase
  2. o cambiar:

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

    a

    obj = JsonConvert.DeserializeObject<Object>(str, new JsonSerializerSettings{ ObjectCreationHandling = ObjectCreationHandling.Replace}); 
    
+0

La estructura vectorial es proporcionada por una biblioteca, por lo que la primera sugerencia no es una opción, pero la segunda funcionó. Me pregunto cuánto trabajo se necesitaría para hacer que Json.NET tenga conocimiento de los tipos de valores y hacer lo que 'ObjectCreationHandling.Replace' haga por defecto en ellos. (Además, 'PreserveReferencesHandling.All' tampoco tiene mucho sentido para los tipos de valor, por lo que no es necesario darles" $ id "). – kloffy

Cuestiones relacionadas