我有以下JSON结构:
{
"Name":"",
"Children":[
{
"ID":"1",
"MetaData":[
{
"Info":{
"GUID":"cdee360d-7ea9-477d-994f-12f492b9e1ed"
},
"Data":{
"Text":"8"
},
"Name":"DataId"
}
]
}
]
}
我希望在数组中展平MetaData和嵌套的Info和Data对象。我还想使用Name字段作为Text值的字段名称,因此它变为" DataId" :" 8"。
{
"Name":"",
"Children":[
{
"ID":"1",
"GUID":"cdee360d-7ea9-477d-994f-12f492b9e1ed",
"DataId":"8"
}
]
}
到目前为止,我已经使用合同解析器让我到目前为止:
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;
}
}
如何获得所需的序列化?
答案 0 :(得分:0)
如果您根本不想修改类型,可以使用LINQ to JSON加载和预处理JSON,如下所示:
// 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>();
为方便起见,使用几种简单的扩展方法:
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);
}
}