且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

JSON序列化-如何使用JSON.net/Newtonsoft展平嵌套的对象结构

更新时间: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);
    }
}