gpt4 book ai didi

c# - 使用 Newtonsoft JSON.Net 在反序列化之前合并源 JSON

转载 作者:太空宇宙 更新时间:2023-11-03 13:02:46 24 4
gpt4 key购买 nike

我有反序列化为 C# 类的 JSON 配置文件。但是,有时,我需要合并配置文件的某些节点。由于 null 和默认值处理的工作方式,我不能简单地序列化对象 1 和对象 2 然后合并(如果对象 2 具有默认值,它不会序列化和覆盖对象 1 的不同属性值)。我宁愿保持我的默认值和空值处理不变。

是否有某种元数据反序列化方法可以连同对象一起访问该特定节点的源 json?我知道这影响深远,但我不太确定如何处理我的情况。

{
"prop1": "value1",
"prop2": "value2",
"defaultProp4Options": {
"subprop1": "subvalue1",
"subprop2": "subvalue2",
"subprop3": "subvalue3"
},
"prop4": [
{
"subprop4": "subvalue4"
},
{
"subprop2": "diff2",
"subprop3": "diff3",
},
{
"subprop1": "diff1",
"subprop5": "subvalue5",
}
]
}

我认为唯一的方法是在反序列化之前进行合并,但我有点卡住了。

var jfoo = JObject.Parse(myconfigjson);
var defaults = jfoo.Values("defaultProp4Options");
var bars = jfoo.Values("prop4");

// ***********
// How do I merge defaults with each bar (bar has precendence) and replace collection?
// ***********

// Use the new merged json to deserialize
var result = JsonConvert.DeserializeObject<Foo>(jfoo.ToString());

任何人都可以让我走上正轨吗?

更新

这让我明白了,但如果您知道更好的方法,请告诉我。

var foo = JObject.Parse(s);
var defaults = jfoo.GetValue("defaultProp4Options");
var bars = jfoo.GetValue("prop4");

var j = new JArray();
foreach (var bar in bars)
{
var baseDefaults = defaults.DeepClone() as JObject;
baseDefaults.Merge(bar);
j.Add(baseDefaults);
}

jfoo.Remove("defaultProp4Options");
jfoo.Property("bars").Value = j;

结果是:

{
"prop1": "value1",
"prop2": "value2",
"prop4": [
{
"subprop1": "subvalue1",
"subprop2": "subvalue2",
"subprop3": "subvalue3",
"subprop4": "subvalue4"
},
{
"subprop1": "subvalue1",
"subprop2": "diff2",
"subprop3": "diff3",
},
{
"subprop1": "diff1",
"subprop2": "subvalue2",
"subprop3": "subvalue3",
"subprop5": "subvalue5"
}
]
}

最佳答案

Json.Net version 6 第 4 版后支持基于 JContainer.Merge 方法的 Merge 操作。

但不幸的是,在您的示例中我们不能直接使用该方法,因为 defaultProp4Options 是一个对象而 prop4 是一个数组,但是如果结构不会改变我们可以在 prop4 中大量迭代并合并项目,这里是一个示例

        var jsonObj = JObject.Parse(json);

var def = (JObject)jsonObj["defaultProp4Options"];
var prop4 = jsonObj["prop4"];

for(int i=0;i<prop4.Count();i++)
{
var item = prop4.ElementAt(i);
var cloneDef =(JObject) def.DeepClone();
cloneDef.Merge(item);
item.Replace(cloneDef);
}

var mergedJson = jsonObj.ToString(); //only used to show new json
Console.WriteLine(mergedJson);

var foo = jsonObj.ToObject<Foo>(); //deserializing to foo

这是输出结果

{
"prop1": "value1",
"prop2": "value2",
"defaultProp4Options": {
"subprop1": "subvalue1",
"subprop2": "subvalue2",
"subprop3": "subvalue3"
},
"prop4": [
{
"subprop1": "subvalue1",
"subprop2": "subvalue2",
"subprop3": "subvalue3",
"subprop4": "subvalue4"
},
{
"subprop1": "subvalue1",
"subprop2": "diff2",
"subprop3": "diff3"
},
{
"subprop1": "diff1",
"subprop2": "subvalue2",
"subprop3": "subvalue3",
"subprop5": "subvalue5"
}
]
}

关于c# - 使用 Newtonsoft JSON.Net 在反序列化之前合并源 JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31860138/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com