【问题标题】:JSON.NET deserialize object using all properties in JSON (overriding all initialized in the constructor) [duplicate]JSON.NET 使用 JSON 中的所有属性反序列化对象(覆盖在构造函数中初始化的所有属性)[重复]
【发布时间】:2018-05-09 14:32:08
【问题描述】:

我有一个包含一些属性的类,其中一个是项目列表。它们都在类的默认无参数构造函数中初始化。我只想拥有这个初始化一切的构造函数。

我的许多课程都是这种情况。

public class ExampleClass
{
    public ExampleClass()
    {
        this.ListProperty = new List<int> { 1, 2 };
        this.APropertyToBeNull = new TypeA();
        this.BPropertyToBeNull = new TypeB();
    }

    public List<int> ListProperty { get; set; }

    public TypeA APropertyToBeNull { get; set; }

    public TypeB BPropertyToBeNull { get; set; }
}

我创建了这个类的一个实例,我将一些属性设置为 null,并将列表属性修改为有 2 个项目

  var instance = new ExampleClass();
  instance.APropertyToBeNull = null;
  instance.BPropertyToBeNull = null;
  instance.ListProperty = new List<int> { 3 };

  var raw = JsonConvert.SerializeObject(instance);            
  var deserialized = JsonConvert.DeserializeObject<ExampleClass>(raw, settings);

  Assert.AreEqual(1, deserialized.ListProperty.Count);
  Assert.IsNull(deserialized.APropertyToBeNull);
  Assert.IsNull(deserialized.BPropertyToBeNull);

当我反序列化时,我找不到完全按照我序列化的方式获取项目的方法。我有两个选择:

  1. 如果我将 ObjectCreationHandling 设置为 Replace,则列表可以很好地反序列化,但 null 属性不再为 null。构造函数初始化了所有内容,反序列化完全替换了列表,但它没有将 null 属性设置为 null
  2. 如果我将 ObjectCreationHandling 设置为 Auto 或 Reuse,则 null 属性将被反序列化为 null,但该列表包含在构造函数中初始化的项目加上 JSON 中的项目。我只想要 JSON 中的那些。

如何在不删除构造函数中所有属性的初始化的情况下获得我序列化的完全相同的项目(我仍然希望在创建新实例的情况下初始化所有属性)。

我已经使用了序列化程序的所有可能设置,但我没有找到解决方案。

作为进一步的限制,我不想为我的所有类添加属性。我对他们中的许多人都有这个问题。

【问题讨论】:

  • 在没有看到一些代码的情况下很难说出你的意思,最好是 MVCE
  • 问题不在于 Json.Net - 是你违反了 SRP。该类应仅用于反序列化。
  • 您已标记此 json.net,但 Json.NET 没有类型 JsonTextSerializer。我可以假设使用JsonConvert 类吗?如果是这样,我做了以下minimal reproducible example 供参考:dotnetfiddle.net/No0QHV
  • @dbc 看起来CollectionClearingContractResolver 解决了它,而且速度不算太慢。谢谢!

标签: c# json serialization json.net deserialization


【解决方案1】:

您可以将[JsonProperty] 属性与DefaultValueHandling 属性一起使用。

鉴于这个类:

public class Foo
{
    [JsonProperty(DefaultValueHandling = DefaultValueHandling.Populate)]
    public string Bar { get; set; }
    public List<bool> Baz { get; set; }

    public Foo()
    {
        Bar = "Not Null";
        Baz = new List<bool>
        {
            false
        };
    }
}

还有这个 JSON:

{ "baz" : [ true ] }

这段代码:

string json = "{ \"baz\" : [ true ] }";

var foo = JsonConvert.DeserializeObject<Foo>(json, new JsonSerializerSettings
{
    ObjectCreationHandling = ObjectCreationHandling.Replace
});

Console.WriteLine(foo.Bar ?? "(null)");
foreach (var b in foo.Baz)
{
    Console.WriteLine(b);
}

将打印:

(null)
True

意味着Bar 字符串将被 JSON 中的值覆盖,即 null,因为它丢失了。

【讨论】:

  • 我不想将它添加到我的所有课程中。我对他们中的许多人都有这个问题
猜你喜欢
  • 2021-05-26
  • 1970-01-01
  • 2018-06-28
  • 2015-03-17
  • 1970-01-01
  • 2014-08-22
  • 1970-01-01
  • 2012-02-07
  • 2021-12-09
相关资源
最近更新 更多