JSON序列化-如何使用JSON.net/Newtonsoft展平嵌套的对象结构 [英] JSON Serialisation - How to flatten nested object structures using JSON.net/Newtonsoft

查看:351
本文介绍了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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆