【问题标题】:Json.NET failing when readonly property is used with object references?当只读属性与对象引用一起使用时,Json.NET 失败?
【发布时间】:2015-04-13 21:26:18
【问题描述】:

编辑 2016-12-05: 这被认为是一个错误并已修复:Readonly property corrupts normal property object references. #486

原帖:

我刚开始使用 Json.NET,但遇到了一些看起来像错误的奇怪行为。

如果反序列化程序遇到最初在只读属性(get; only)中定义的对象引用(“$ref”:“2”),则反序列化失败并返回 null。

public class Parent
{
    public Child ReadOnlyChild
    {
        get
        {
            return Child;
        }
    }

    public Child Child {get; set;}
}
public class Child
{
}

序列化:

Parent p = new Parent() { Child = new Child() };
JsonConvert.SerializeObject(p, new JsonSerializerSettings()
{ Formatting = Formatting.Indented,
  PreserveReferencesHandling = PreserveReferencesHandling.Objects });

序列化:

{
  "$id": "1",
  "ReadOnlyChild": {
    "$id": "2",
  },
  "Child": {
    "$ref": "2"
  }
}

反序列化(并重新序列化以显示更改):

{
  "$id": "1",
  "ReadOnlyChild": null,
  "Child": null
}

这是预期的行为、错误还是我遗漏了什么?

请注意,有时需要 [JsonProperty(Order = #)] 来强制序列化程序首先对 ReadOnlyChild 进行操作。无论如何,上述 Serialized JSON 块将无法正确反序列化,即使该类已被修改为先反序列化 Child。

编辑:我关心的是 Child 属性被清空,而不是 ReadOnlyChild 被 Json.NET 以某种方式分配了一个值

谢谢!

【问题讨论】:

  • 我从不使用引用跟踪,但是查看您的数据,似乎它正在为您的ReadOnlyChild 创建一个“id”,您很普通Child 属性是引用 i> 那个 id,在反序列化时,由于它无法恢复 ReadOnlyChild,整个参考跟踪业务都搞砸了。
  • @KirkWoll:这也是我得出的结论。我理解无法将 Child 对象分配给 ReadOnlyChild(毕竟没有集合),但它会丢弃该对象,而不是等到 Child 属性再次被引用。
  • 这纯粹是我的猜测,但我怀疑发生的事情是 json.net 成功反序列化了 ReadOnlyChild 的值,尝试将其放在该属性中 - - 失败,因为它不可写 - 并最终留下一个引用(在其内部模型中),id "2" 的值现在包含在 ReadOnlyChild 中(由于分配失败,它没有任何值)。然后它获取Child 的值"$ref": "2",尝试将其解析为ReadOnlyChild 的值,并将其值也设置为null
  • @Shoebox 感谢您回来更新您的问题。

标签: c# .net json serialization json.net


【解决方案1】:

您是否考虑过阻止该属性被 Json.Net 序列化?

public class Parent
{
    [JsonIgnore] 
    public Child ReadOnlyChild
    {
        get
        {
            return Child;
        }
    }

    public Child Child {get; set;}
}

【讨论】:

  • 这是一个很好的解决方法,很可能是我的最终解决方案。
  • 如果您不需要 Json 中的 ReadOnly 字段,那就太好了。如果您确实需要它,但希望在它返回时忽略该值,则不是很好。
  • @Shoebox 我认为这不仅仅是一种解决方法:D ReadOnlyChild 在这种情况下是一个计算值,根本不需要序列化它
  • 问题已修复。我编辑了 OP 以反映这一点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-03-12
  • 1970-01-01
  • 2015-09-03
  • 1970-01-01
  • 1970-01-01
  • 2021-01-11
  • 2016-03-31
相关资源
最近更新 更多