【问题标题】:Is it possible to flatten (hide) a Dictionary variable name?是否可以展平(隐藏)字典变量名?
【发布时间】:2018-12-05 06:30:48
【问题描述】:

在处理一个我想序列化为 JSON 的类时,我遇到了一个我不确定如何最好地解决的情况。它与具有固定和随机属性的 JSON 结构有关(固定:始终具有相同的属性名称,随机:它们的名称是随机的)。此外,固定属性始终为string 类型,随机属性始终为MyJsonClass2 类型。

例如:

{
 "fixedName1": "value1",
 "fixedName2": "value2",
 "randomName1": { ... },
 "randomNameN": { ... }
}

这可以使用Dictionary<string, object> 来表示。但是因为总是给出fixedName1fixedName2,所以我希望将它们作为固定声明,并且只有字典中的变量如下:

class MyJson
{
    public string fixedName1 = "blah1";
    public string fixedName2 = "blah2";

    public Dictionary<string, MyJsonClass2> randomNames = new Dictionary<string, MyJsonClass2>();
}

这里的问题是,当它被序列化时,来自randomNames 的值被包含在一个名为 randomNames 的属性中,这是有道理的,但这不是我希望看到的。有没有办法告诉 Newtonsoft JSON 序列化器 ignore 字典名称?或者定义这样一个类的最佳方式是什么?

【问题讨论】:

  • 你可以创建一个JsonConverter。不确定是否有更好的选择。
  • 你可以实现一个自定义的 JsonConverter。但是,您所描述的似乎有些奇怪。你为什么要这个?
  • JsonTypedExtensionDataAttributeTypedExtensionDataConverter&lt;MyJson&gt;this answerHow to deserialize a child object with dynamic (numeric) key names? 可能是您需要的。同意吗?

标签: c# json serialization json.net


【解决方案1】:

在您的 json 中,您的一些键/值数据是固定的,而一些键/值对数据是随机的,或者简单地说它是动态的。

然后您可以声明固定键/值对的属性。但是当你问到它的动态和问题时,问题就出现了。

所以 Newtonsoft.json 有一个可以在这里使用的功能,那就是[JsonExtensionData]Read more

现在在序列化对象时写入扩展数据。读取和写入扩展数据可以自动往返所有 JSON,而无需将每个属性添加到您要反序列化的 .NET 类型。只声明您感兴趣的属性,让扩展数据完成其余的工作。

现在您可以像这样为固定的键/值配对数据添加属性。

public string fixedName1 {get;set;}
public string fixedName2 {get;set;}

对于动态或随机键/值对,您需要使用 [JsonExtensionData] 装饰您的 Dictionary 属性。喜欢

[JsonExtensionData]
public Dictionary<string, JToken> randomNames {get;set;}

所以你的班级会是这样的

class MyJson
{
    public string fixedName1 {get;set;}
    public string fixedName2 {get;set;}

    [JsonExtensionData]
    public Dictionary<string, JToken> randomNames {get;set;}
}

现在尝试使用上述类序列化您的数据,您将永远不会在输出序列化 json 中获得字典名称。

你可以试试上面的类

MyJson myJson = new MyJson();
myJson.fixedName1 = "ABC";
myJson.fixedName2 = "PQR";
myJson.randomNames = new Dictionary<string, JToken>();
myJson.randomNames.Add("randomName1", JToken.FromObject(new MyJsonClass2 { Name = "QWERTY" }));
myJson.randomNames.Add("randomNameN", JToken.FromObject(new MyJsonClass2 { Name = "ZXCVBNM" }));

string json = JsonConvert.SerializeObject(myJson);

输出:

【讨论】:

  • 感谢您的解决方案。在我勾选你的答案之前,我想完全测试它,但后来我被其他一些工作搁置了......但我现在已经检查过了,现在输出看起来很棒:)
  • 很高兴听到,欢迎 :)
猜你喜欢
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
  • 1970-01-01
  • 2016-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多