【问题标题】:Newtonsoft.JsonConvert.DeserializeObject<T> works on one child object but not the restNewtonsoft.JsonConvert.DeserializeObject<T> 适用于一个子对象,但不适用于其余子对象
【发布时间】:2021-02-06 23:57:36
【问题描述】:

这是一个真正的谜题。

我在 Unity 中使用 Newtonsoft.Json 序列化 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} 为什么?

您会注意到centernormalv1 都是等价的,所以我知道解析这些值不是问题。原始 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

【问题讨论】:

  • 3) FloatParseHandling 控制在数据模型中未明确指定时如何解析浮点数,例如解析为JTokendynamic 时。它应该不会影响明确键入为 float 的属性如何从 JSON 字符串反序列化。
  • 嗨@dbc,非常感谢您的关注。我已经用更详尽的例子更新了这个问题。要重现的完整源代码将有很多 MB,但我尽可能使用实际输出数据作为完整示例提供。
  • 无法在 .NET Core 3.1.5 上重现,请参阅 dotnetfiddle.net/5LlWnZ。也许在解析float 字段时存在一些特定于Unity 的问题?您可以尝试将它们更改为double 并重新测试吗?还是将它们更改为自动属性并重新测试?
  • 我尝试使用 double 和 auto 字段,降级到 Json.net 3.5 并升级到 4.5,还尝试粘贴我的问题中给出的字符串文字(带有转义引号),仍然得到相同的无穷大错误。

标签: c# json unity3d json.net deserialization


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 2017-06-21
    • 2022-11-15
    • 2022-11-09
    • 2015-12-01
    • 1970-01-01
    • 2013-09-22
    • 2013-12-05
    • 1970-01-01
    • 2021-04-28
    相关资源
    最近更新 更多