Search code examples
c#jsonjson.netdeserializationjson-deserialization

How to deserialize an array of an array of objects using Newtonsoft


I am trying to deserialize an Object like this. My issue is that it is blowing up trying to deserialize the inner items.

{
    "outeritems": [{        
        "inneritems": [
            [{
                "itemid": "1"                
            }, {
                "itemid": "2"                
            }]
        ]
    }]    
}

I have already tried

public List<List<inneritems>> inneritems{ get; set; }

also

public List<inneritems> inneritems{ get; set; }

I'm thinking this might have to have a custom JSON converter


Solution

  • I had to create a custom Newtonsoft JSON Converter

    This is what I did.

    Created A JsonCreationConverter Base Class

    public abstract class JsonCreationConverter<T> : JsonConverter
    {        
        protected abstract T Create(Type objectType, JObject jObject);
    
        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            throw new NotImplementedException("Unnecessary because CanWrite is false. The type will skip the converter.");
        }
    
        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
                return null;
    
            JObject jObject = JObject.Load(reader);           
    
            T target = Create(objectType, jObject);
    
            // Populate the object properties
            serializer.Populate(jObject.CreateReader(), target);
    
            return target;
        }
    
        public override bool CanConvert(Type objectType)
        {
            return typeof(T).IsAssignableFrom(objectType);
        }
    
        public override bool CanWrite
        {
            get { return false; }
        }
    }
    

    Created A Costume Converter that inherited my base class

    public class OuterConverter :
            JsonCreationConverter<OuterItems>
    {
            protected override OuterItems Create(Type objectType, JObject jObject)
            {
                OuterItems outeritems =
                    new OuterItems();
    
                var properties = jObject.Properties().ToList();
                outeritems.InnerItems = GetInnerItems((object)properties[0].Value);
    
                return outeritems;
            }
    
            // Need to iterate through list so creating a custom object
            private List<List<InnerItems>> GetInnerItems(object propertyValue)
            {
    
                string sinneritems = "";
                object inneritems = propertyValue;
                sinneritems = String.Format("{0}", inneritems);
    
                sinneritems = sinneritems.Insert(1, "{ \"Items\": [");
                sinneritems = sinneritems.Substring(1, sinneritems.Length - 1);
                sinneritems = sinneritems.Remove(sinneritems.Length - 1);
    
                sinneritems += "]}";
    
                dynamic results = JObject.Parse(sinneritems);
    
                List<List<InnerItems>> innerItemsList = new List<List<InnerItems>>();
    
                List<InnerItems> linnerItems = new List<InnerItems>();
    
                foreach (var items in results.Items)
                {
                    foreach (var item in items)
                    {
                        string sItem = String.Format("{0}", item);
                        InnerItems ninneritems = Newtonsoft.Json.JsonConvert.DeserializeObject<InnerItems>(sItem);
                        linnerItems.Add(ninneritems);
                    }
                    innerItemsList.Add(linnerItems);
                }
    
                return innerItemsList;
            }
    }
    

    Append the New Converter on the Newtonsoft Deserializer

    return Newtonsoft.Json.JsonConvert.DeserializeObject<T>(result.ToString(),
                 new OuterConverter());