[Fork] Deep Nested Object Properties Json Serialization

CSharp · Console

/Program.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class Program
{
    public static void Main()
    {
        var dataMapperModels = new List<DataMapper>();

        var model = new DataMapper
        {
            Name = "performanceLevels",
            SubDataMappers = new List<DataMapper>()
            {
                new DataMapper()
                {
                    Name = "performanceLevel_1",
                    SubDataMappers = new List<DataMapper>()
                    {
                        new DataMapper()
                        {
                            Name = "title",
                            DataMapperProperty = new DataMapperProperty()
                                    {
                                        Source = "column",
                                        SourceColumn = "title-column",
                                        DataType = "string",
                                        Default = "N/A",
                                        SourceTable = null,
                                        Value = null
                                    }
                        }
                    }
                }
            }
        };


        dataMapperModels.Add(model);

        var jsonMap = JsonConvert.SerializeObject(dataMapperModels, new JsonSerializerSettings()
        {
            Formatting = Formatting.Indented
        });

        Console.WriteLine(jsonMap);
    }

    /* GOAL:
    [
       {
          "performanceLevels":[
             {
                "performanceLevel_1":{
                   "title":{
                      "data-type":"string",
                      "source":"column",
                      "source-column":"title-column",
                      "default":"N/A"
                   }
                }
             }
          ]
       }
    ]
    */

    public class DataMapperJsonSerializer : JsonConverter
    {
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            if (value is DataMapper)
            {
                var dataMapper = (DataMapper)value;
                if (dataMapper.SubDataMappers.Any())
                {
                    writer.WriteStartObject();
                    writer.WritePropertyName(dataMapper.Name);
                    writer.WriteStartArray();
                    //
                    dataMapper.SubDataMappers.ForEach(sub =>
                    {
                        writer.WriteStartObject();
                        writer.WritePropertyName(sub.Name);
                        serializer.Serialize(writer, sub.SubDataMappers);
                        //if (sub.SubDataMappers.Any())
                        //{
                        //    sub.SubDataMappers.ForEach(tri =>
                        //    {
                        //        writer.WriteStartObject();
                        //        writer.WritePropertyName(tri.Name);
                        //        serializer.Serialize(writer, tri.DataMapperProperty);
                        //        writer.WriteEndObject();
                        //    });
                        //}
                        writer.WriteEndObject();
                    });
                    //
                    writer.WriteEndArray();
                    writer.WriteEndObject();
                }
                else
                {
                    writer.WriteStartObject();
                    writer.WritePropertyName(dataMapper.Name);
                    serializer.Serialize(writer, dataMapper.DataMapperProperty);
                    writer.WriteEndObject();
                }
            }
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            JObject jsonObject = JObject.Load(reader);
            var properties = jsonObject.Properties().ToList();
            return new DataMapper()
            {
                Name = properties[0].Name,
                DataMapperProperty = (DataMapperProperty)properties[0].Value
            };
        }

        public override bool CanConvert(Type objectType)
        {
            return typeof(DataMapper).IsAssignableFrom(objectType);
        }
    }


    [JsonConverter(typeof(DataMapperJsonSerializer))]
    public class DataMapper
    {
        public DataMapper()
        {
            SubDataMappers = new List<DataMapper>();
        }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public string Name { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public DataMapperProperty DataMapperProperty { get; set; }

        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public List<DataMapper> SubDataMappers { get; set; }
    }

    public class DataMapperProperty
    {
        [JsonProperty(PropertyName = "data-type", NullValueHandling = NullValueHandling.Ignore)]
        public string DataType { get; set; }

        [JsonProperty(PropertyName = "source", NullValueHandling = NullValueHandling.Ignore)]
        public string Source { get; set; }

        [JsonProperty(PropertyName = "source-column", NullValueHandling = NullValueHandling.Ignore)]
        public string SourceColumn { get; set; }

        [JsonProperty(PropertyName = "source-table", NullValueHandling = NullValueHandling.Ignore)]
        public string SourceTable { get; set; }

        [JsonProperty(PropertyName = "default", NullValueHandling = NullValueHandling.Ignore)]
        public string Default { get; set; }

        [JsonProperty(PropertyName = "value", NullValueHandling = NullValueHandling.Ignore)]
        public string Value { get; set; }

        public static explicit operator DataMapperProperty(JToken v)
        {
            return new DataMapperProperty()
            {
                DataType = v.Value<string>("data-type"),
                Source = v.Value<string>("source"),
                SourceColumn = v.Value<string>("source-column"),
                SourceTable = v.Value<string>("source-table"),
                Default = v.Value<string>("default"),
                Value = v.Value<string>("value")
            };
        }
    }
}
;