更新时间:2022-03-30 22:57:50
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);
}
}