JSON序列化-如何使用JSON.net/Newtonsoft展平嵌套的对象结构 [英] JSON Serialisation - How to flatten nested object structures using JSON.net/Newtonsoft
本文介绍了JSON序列化-如何使用JSON.net/Newtonsoft展平嵌套的对象结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我具有以下JSON结构:
I have the following JSON structure :
{
"Name":"",
"Children":[
{
"ID":"1",
"MetaData":[
{
"Info":{
"GUID":"cdee360d-7ea9-477d-994f-12f492b9e1ed"
},
"Data":{
"Text":"8"
},
"Name":"DataId"
}
]
}
]
}
,我想展平MetaData以及数组中嵌套的Info和Data对象.我还想将名称"字段用作文本"值的字段名称,因此它变为"DataId":"8".
and I want to flatten the MetaData and nested Info and Data objects in the array. I also want to use the Name field as a field name for Text value so it becomes "DataId" : "8".
{
"Name":"",
"Children":[
{
"ID":"1",
"GUID":"cdee360d-7ea9-477d-994f-12f492b9e1ed",
"DataId":"8"
}
]
}
到目前为止,我已经使用了Contract Resolver进行了深入了解:
So far I've used a Contract Resolver to get me so far:
private class DynamicContractResolver : DefaultContractResolver
{
private readonly List<string> _propertiesToSerialize;
private readonly List<string> _itemTypeNames;
public DynamicContractResolver(List<string> propertiesToSerialize, List<string> itemTypeNames)
{
_propertiesToSerialize = propertiesToSerialize;
_itemTypeNames = itemTypeNames;
}
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
var properties = base.CreateProperties(type, memberSerialization);
properties = properties.Where(p => _propertiesToSerialize.Contains(p.PropertyName)).ToList();
}
return properties;
}
}
如何进行所需的序列化?
How do I go about getting my desired serialisation?
推荐答案
If you don't want to modify your types at all, you can use LINQ to JSON to load and preprocess your JSON, like so:
// Load the JSON into an intermediate JObject
var rootObj = JObject.Parse(json);
// Restructure the JObject hierarchy
foreach (var obj in rootObj.SelectTokens("Children[*]").OfType<JObject>())
{
var metadata = obj.SelectToken("MetaData[0]"); // Get the first entry in the "MetaData" array.
if (metadata != null)
{
// Remove the entire "Metadata" property.
metadata.Parent.RemoveFromLowestPossibleParent();
// Set the name and value
var name = metadata.SelectToken("Name");
var id = metadata.SelectToken("Data.Text");
if (name != null && id != null)
obj[(string)name] = (string)id;
// Move all other atomic values.
foreach (var value in metadata.SelectTokens("..*").OfType<JValue>().Where(v => v != id && v != name).ToList())
value.MoveTo(obj);
}
}
Debug.WriteLine(rootObj);
// Now deserialize the preprocessed JObject to the final class
var root = rootObj.ToObject<RootObject>();
为方便起见,使用了两种简单的扩展方法:
Using a couple of simple extension methods for convenience:
public static class JsonExtensions
{
public static void RemoveFromLowestPossibleParent(this JToken node)
{
if (node == null)
throw new ArgumentNullException();
var contained = node.AncestorsAndSelf().Where(t => t.Parent is JArray || t.Parent is JObject).FirstOrDefault();
if (contained != null)
contained.Remove();
}
public static void MoveTo(this JToken token, JObject newParent)
{
if (newParent == null)
throw new ArgumentNullException();
var toMove = token.AncestorsAndSelf().OfType<JProperty>().First(); // Throws an exception if no parent property found.
toMove.Remove();
newParent.Add(toMove);
}
}
这篇关于JSON序列化-如何使用JSON.net/Newtonsoft展平嵌套的对象结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文