I have JSON configuration files that I deserialize into c# classes. However, sometimes, I have a need to merge certain nodes of the config files. I can't simply serialize object 1 and object 2 and then merge because of the way null and default value handling work (if object 2 has a default value, it won't serialize and overwrite object 1's differing property value). I'd prefer to keep my default and null value handling untouched.
Is there some sort of metadata deserialization method that along with the object, I'd have access to the source json of that particular node? I know this is far reaching, but I'm not quite sure how else to handle my situation.
{
"prop1": "value1",
"prop2": "value2",
"defaultProp4Options": {
"subprop1": "subvalue1",
"subprop2": "subvalue2",
"subprop3": "subvalue3"
},
"prop4": [
{
"subprop4": "subvalue4"
},
{
"subprop2": "diff2",
"subprop3": "diff3",
},
{
"subprop1": "diff1",
"subprop5": "subvalue5",
}
]
}
I'm thinking the only way to do this is to merge prior to deserialization, but I'm a little stuck.
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());
Can anybody get me on the right track?
UPDATE
This gets me there, but let me know if you know of a better way.
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;
Which results in:
{
"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"
}
]
}