我有JSON配置文件,我将其反序列化为c#类。但是,有时,我需要合并配置文件的某些节点。我不能简单地序列化对象1和对象2然后合并,因为null和默认值处理工作的方式(如果对象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"
}
]
}
答案 0 :(得分:1)
Json.Net第6版第4次发布后,它支持基于JContainer.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"
}
]
}