首页 > 解决方案 > Newtonsoft.JsonConvert.DeserializeObject适用于一个子对象,但不适用于其余对象

问题描述

这是一个真正的难题。

我在 Unity 中使用 Newtonsoft.Json 来序列化一个 HexTile 列表,每个 HexTile 都有一个 Hexagon,它会生成这个看起来不错的 JSON,并且在我的 Node 应用程序中反序列化就好了数据源:

PolySphere sphere = new PolySphere(Vector3.zero, WorldManager.worldScale, WorldManager.worldSubdivisions);
JsonSerializer serializer = new JsonSerializer();
serializer.Formatting = Formatting.Indented;
using (StreamWriter sw = new StreamWriter(Application.dataPath+"\\Resources\\baseworld.json"))   // Note DO NOT use any encoding options
using (JsonWriter writer = new JsonTextWriter(sw))
{
    serializer.Serialize(writer, sphere);
}

^ 这会产生这个(好的)JSON:

{
  "hexTiles": [
    {
      "index": 0,
      "height": 0.0,
      "hexagon": {
        "center": {
          "x": 0.561780632,
          "y": 0.5952229,
          "z": -0.574553967
        },
        "normal": {
          "x": 0.561780632,
          "y": 0.5952229,
          "z": -0.574553967
        },
        "v1": {
          "x": 0.561780632,
          "y": 0.5952229,
          "z": -0.574553967
        },
        "v2": {
          "x": 17.0217762,
          "y": 17.6508,
          "z": -18.0395374
        },
        "v3": {
          "x": 16.5437584,
          "y": 18.1888123,
          "z": -17.94959
        },
        "v4": {
          "x": 16.6196823,
          "y": 18.6517467,
          "z": -17.3958359
        },
        "v5": {
          "x": 17.17278,
          "y": 18.5775471,
          "z": -16.9318352
        },
        "v6": {
          "x": 17.6508,
          "y": 18.0395355,
          "z": -17.0217762
        },
        "isPentagon": false,
        "scale": 30.4333477
      },
      "type": 0,
      "neighbors": [
        1,
        2,
        3,
        4,
        9,
        10
      ],
      "passable": true
    }
  ]
}

但是,结果不会正确反序列化回 PolySphere。

TextAsset text = Resources.Load<TextAsset>("baseworld");
PolySphere baseWorld = JsonConvert.DeserializeObject<PolySphere>(text.text);
// The baseWorld.hexTiles[0].hexagon.center is Infinity, as shown by logging:
Debug.Log(JsonConvert.SerializeObject(baseWorld));

^ 在 Unity 中重新解析后的 Debug.Log:

{"hexTiles":[
  {
    "index":0,"height":0.0,
    "hexagon":{
      "center":{"x":"Infinity","y":"Infinity","z":"-Infinity"},
      "normal":{"x":0.561780632,"y":0.5952229,"z":-0.574553967},
      "v1":{"x":"Infinity","y":"Infinity","z":"-Infinity"},
      "v2":{"x":"Infinity","y":"Infinity","z":"-Infinity"},
      "v3":{"x":"Infinity","y":"Infinity","z":"-Infinity"},
      "v4":{"x":"Infinity","y":"Infinity","z":"-Infinity"},
      "v5":{"x":"Infinity","y":"Infinity","z":"-Infinity"},
      "v6":{"x":"Infinity","y":"Infinity","z":"-Infinity"},
      "isPentagon":false,"scale":"Infinity"
    },
    "type":0,
    "neighbors":[1,2,3,4,9,10],
    "passable":true
  }
]}

polySphere.hexTiles[0].hexagon.normal 解析正确,但center、v1、v2 等都以 {infinity、infinity、-infinity} 出现, 为什么?

您会注意到center,normalv1都是等价的,所以我知道解析值不是问题。原始 JSON 的格式似乎正确,并且可以在 Node.js 中使用。那么这里发生了什么?

原始类结构:

[Serializable]
public class PolySphere
{
  public List<HexTile> hexTiles;
}
[Serializable]
public class HexTile
{
  public int index;
  public float height = 1;
  public Hexagon hexagon;
  public int type;
  public int[] neighbors;
}

[Serializable]
public class Hexagon
{
  public SerializableVector3 center, normal, v1, v2, v3, v4, v5, v6;
  public bool isPentagon;
  private float _scale;
  public float scale { get{return _scale;}
  set{
        v1 /= v1.magnitude;
        v1 *= value;
        v2 /= v2.magnitude;
        v2 *= value;
        v3 /= v3.magnitude;
        v3 *= value;
        v4 /= v4.magnitude;
        v4 *= value;
        v5 /= v5.magnitude;
        v5 *= value;
        v6 /= v6.magnitude;
        v6 *= value;
        center = (v1 + v2 + v3 + v4 + v5 + v6) / 6f;
        _scale = center.magnitude;
    }

} }

[System.Serializable]
 public struct SerializableVector3
 {
    public float x, y, z;
}

tl; dr我的 Hexagon 类中的 8 个中的一个 SerializableVector3 正确反序列化,其余的全部输出为Infinity

标签: c#jsonunity3djson.netdeserialization

解决方案


经过反复试验,我发现问题出在 Hexagon.scale 属性上。通过将其从序列化中删除,反序列化的其余部分开始正常工作。


推荐阅读