skip to Main Content

I’m using newtonsoft json, and I need to serialize/deserialize this kind of json:

[
  {
    "value": "value1",
    "field": "field1"
  },
  {
    "value": "value2",
    "field": "field2"
  },
  {
    "value": "value3",
    "field": "field3"
  },
  [
    {
      "value": "value4",
      "field": "field4"
    },
    {
      "value": "value4",
      "field": "field5"
    }
  ]
]

As you can see, I can have an object or a list of this object at the same level. I’ve created a class for the object but I don’t know how to make the serialization process this kind of json, or if it’s possible to do.

EDIT: I don’t have the choice to process that json as it comes to me. So please, if you think I like this, you’re wrong.

2

Answers


  1. Chosen as BEST ANSWER

    Here is the solution I found thanks to your help:

    public class Item
    {
        public string Value { get; set; }
        public string Field { get; set; }
    }
    
    public class ItemContainer
    {
        public List<Item> Items { get; set; }
        public List<List<Item>> NestedItems { get; set; }
    }
    
    public class ItemContainerConverter : JsonConverter<ItemContainer>
    {
        public override ItemContainer ReadJson(JsonReader reader, Type objectType, ItemContainer existingValue,
            bool hasExistingValue, JsonSerializer serializer)
        {
            var jsonObject = JArray.Load(reader);
            var itemContainer = new ItemContainer
            {
                Items = new List<Item>(),
                NestedItems = new List<List<Item>>()
            };
    
            foreach (var token in jsonObject)
            {
                if (token.Type == JTokenType.Array)
                {
                    var nestedItemList = token.ToObject<List<Item>>();
                    itemContainer.NestedItems.Add(nestedItemList);
                }
                else if (token.Type == JTokenType.Object)
                {
                    var item = token.ToObject<Item>();
                    itemContainer.Items.Add(item);
                }
            }
    
            return itemContainer;
        }
    
        public override void WriteJson(JsonWriter writer, ItemContainer value, JsonSerializer serializer)
        {
            writer.WriteStartArray();
    
            foreach (var item in value.Items)
            {
                serializer.Serialize(writer, item);
            }
    
            if (value.NestedItems != null && value.NestedItems.Any())
            {
                writer.WriteStartArray();
                foreach (var nestedItem in value.NestedItems.SelectMany(nestedList => nestedList))
                {
                    serializer.Serialize(writer, nestedItem);
                }
                writer.WriteEndArray();
            }
    
            writer.WriteEndArray();
        }
    }
    

    And there is how to use it:

    var settings = new JsonSerializerSettings()
    {
        ContractResolver = new DefaultContractResolver
        {
            NamingStrategy = new SnakeCaseNamingStrategy()
        }
    };
    settings.Converters.Add(new ItemContainerConverter());
    
    var rootObject = JsonConvert.DeserializeObject<ItemContainer>(jsonString, settings);
    var json = JsonConvert.SerializeObject(rootObject, settings);
    

  2. you can create a custom json converter

    Result result = JsonConvert.DeserializeObject<Result>(json, new ArrayJsonConverter())
    
    public class ArrayJsonConverter : JsonConverter<Result>
    {
        public override Result ReadJson(JsonReader reader, Type objectType, Result existingValue, bool hasExistingValue, JsonSerializer serializer)
        {
            JArray jArr = JArray.Load(reader);
    
            var result = new Result { Items = new List<Item>(), ListItems = new List<List<Item>>() };
    
            foreach (var item in jArr)
                if (item.Type == JTokenType.Array) result.ListItems.Add(item.ToObject<List<Item>>());
                else result.Items.Add(item.ToObject<Item>());
    
            return result;
        }
    
        public override void WriteJson(JsonWriter writer, Result value, JsonSerializer serializer)
        {
            throw new NotImplementedException();
        }
    }
    
    public class Result
    {
        public List<Item> Items { get; set; }
        public List<List<Item>> ListItems { get; set; }
    }
    
    public class Item
    {
        public string value { get; set; }
        public string field { get; set; }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search