【问题标题】:JSON Deserialization with property default value not working具有属性默认值的 JSON 反序列化不起作用
【发布时间】:2018-10-16 13:58:18
【问题描述】:

我正在使用 Newtonsoft 反序列化文件中的数据。当我从两组不同的数据中反序列化两个不同的实例时,两个实例的属性最终都具有相同的值。我创建了一个小项目来重现这个问题。这是我的 2 个 JSON 文件

文件1.json:

{
  "Name": "File1",
  "SomeProperty":
  {
    "Value": 1 
  }
}

文件2.json:

{
  "Name": "File2",
  "SomeProperty":
  {
    "Value": 2 
  }
}

SomeProperty.cs

namespace Json
{
  public class SomePropertyDto
  {
    public static SomePropertyDto Default = new SomePropertyDto
    {
      Value = 0
    };

    public int Value { get; set; }
  }
}

FileDataDto.cs

namespace Json
{
  public class FileDataDto
  {
    public string Name { get; set; }

    public SomePropertyDto SomeProperty
    {
      get => someProperty;
      set => someProperty = value;
    }

    private SomePropertyDto someProperty = SomePropertyDto.Default;
  }
}

程序.cs

using System.IO;
using Newtonsoft.Json;

namespace Json
{
  class Program
  {
    static void Main(string[] args)
    {
      string json1 = File.ReadAllText("File1.json");
      string json2 = File.ReadAllText("File2.json");

      FileDataDto fileData1 = JsonConvert.DeserializeObject<FileDataDto>(json1);
      FileDataDto fileData2 = JsonConvert.DeserializeObject<FileDataDto>(json2);
    }
  }
}

在反序列化两个 FileDataDto 实例后,它们的 SomeProperty 值都相同。但是,如果我不将 FileDataDto someProperty 字段初始化为 SomePropertyDto.Default,

private SomePropertyDto someProperty;// = SomePropertyDto.Default;

它工作正常。如果我将初始化包含在默认值中

private SomePropertyDto someProperty = SomePropertyDto.Default;

在反序列化 fileData1 后,SomeProperty 的值如预期的那样等于 1。但是,在反序列化 fileData2 后,fileData1 和 FileData2 实例的 SomeProperty 值都等于 2,这不是预期的。

【问题讨论】:

    标签: json json.net deserialization


    【解决方案1】:

    根据https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/JsonSerializerSettings.cs#L46,默认的对象创建设置是“Auto”,意思是https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/ObjectCreationHandling.cs#L34

    重用现有对象,在需要时创建新对象。

    因此,当您的 Default 对象存在时,someProperty 将保留此,所有 FileDataDto 实例的相同共享对象。

    如果您需要默认值,请提供自定义的 JsonSerializerSettings(ObjectCreationHandling 设置为 Replace)。

    【讨论】:

    • 谢谢。因此,必须注意不要在要反序列化的类中使用对象属性的默认值,因为这可能会导致很多错误,就像我的情况一样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-31
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-27
    相关资源
    最近更新 更多