Search code examples
c#jsonserializationdeserializationjson-deserialization

I have serialized nested objects with JSON, how do I deserialize them?


I keep getting "Additional text encountered after finished reading JSON content" when deserializing. I've tried placing the whole "output" into square brackets, didn't work out.

Full error message

Newtonsoft.Json.JsonReaderException: 
'Error reading JObject from JsonReader. Current JsonReader item is not an object: 
StartArray. Path '', line 1, position 1.'

These are my 2 objects. NOTE: Values are currently commented for easier "output" reading.

class ItemSerObj
{
    public string ItemName { get; set; }
    /*
    public string Value { get; set; }
    public string Quality { get; set; }
    public string TimeStamp { get; set; }*/
}

.

class GroupSerObj
{
    public string GroupName { get; set; }
    /*
    public string UpdateRate { get; set; }
    public string Active { get; set; }*/
    public List<ItemSerObj> Items { get; set; }
}

How I serilzed them.

JsonSerializer serializer = new JsonSerializer();
        using (StreamWriter sw = new StreamWriter(path + "\\data.txt"))
        {
            using (JsonWriter writer = new JsonTextWriter(sw))
            {
                foreach (ListViewItem group in lV_groups.Items)
                {
                    List<ItemSerObj> itemsObj = new List<ItemSerObj>();
                    tempOPCServer.opcGroup = tempOPCServer.opcServer.OPCGroups.GetOPCGroup(group.SubItems[0].Text);
                    foreach (OPCItem item in tempOPCServer.opcGroup.OPCItems)
                    {
                        ListViewItem listViewItem = new ListViewItem();
                        listViewItem.Name = item.ItemID.Substring(item.ItemID.LastIndexOf('.') + 1);
                        itemsObj.Add(
                        new ItemSerObj
                        {
                            ItemName = listViewItem.Name
                            /*ItemName = item.SubItems[0].Text/*,
                            Value = item.SubItems[1].Text,
                            Quality = item.SubItems[2].Text,
                            TimeStamp = item.SubItems[3].Text*/
                        });
                    }

                    GroupSerObj serializeGroup = new GroupSerObj
                    {
                        GroupName = group.SubItems[0].Text,/*
                        UpdateRate = group.SubItems[1].Text,
                        Active = group.SubItems[2].Text,*/
                        Items = itemsObj
                    };

                    serializer.Serialize(writer, serializeGroup);
                }
            }
        }

The output.

{"GroupName":"Group0","Items":[{"ItemName":"Int1"},{"ItemName":"Money"},{"ItemName":"Int4"},{"ItemName":"Int2"}]}{"GroupName":"Group1","Items":[]}{"GroupName":"Group2","Items":[]}

More readable sorting

{"GroupName":"Group0","Items":[
    {"ItemName":"Int1"},
    {"ItemName":"Money"},
    {"ItemName":"Int4"},
    {"ItemName":"Int2"}]}
{"GroupName":"Group1","Items":[
    ]}
{"GroupName":"Group2","Items":[
]}

What I've tried to deserialize it.

string fromJson;
        using (StreamReader sr = new StreamReader(path + "\\data.txt"))
        {
            fromJson = @sr.ReadLine();
        }
        JObject fromJsonObject = JObject.Parse(fromJson); //Where exeption occurs.


        IList<JToken> results = fromJsonObject["Items"]["ItemName"].Children().ToList();

        IList<GroupSerObj> deserResults = new List<GroupSerObj>();

        foreach(JToken result in results)
        {
            GroupSerObj deserResult = result.ToObject<GroupSerObj>();
            deserResults.Add(deserResult);
        }

Solution

  • For me it looks like your output is wrong. Its an array of objects (multiple groups) so it should be surrounded by [ and ] and each object separated by a comma (,).

    Your output should look like this:

    [{"GroupName":"Group0","Items":[{"ItemName":"Int1"},{"ItemName":"Money"},{"ItemName":"Int4"},{"ItemName":"Int2"}]},{"GroupName":"Group1","Items":[]},{"GroupName":"Group2","Items":[]}]
    

    You are using a JObject to Parse the Array, but when paring an array we need the JArray, so it should be:

    JArray fromJsonObject = JArray.Parse(fromJson); //Where exeption occurs.
    for (int i = 0; i < fromJsonObject.Count; i++)
       {
           IList<GroupSerObj> deserResults = new List<GroupSerObj>();
           var deserResult = fromJsonObject[i].ToObject<GroupSerObj>();
           deserResults.Add(deserResult);
       }