Home > Software engineering >  newtonsoft deserialize group of objects
newtonsoft deserialize group of objects

Time:07-28

TL;DR How do I convert json data that looks like this into a C# object using Newtonsoft.json and JsonConvert.DeserializeObject?

{"start":true,"result":{"label":"Setup Account","item":"name"}}
{"start":false,"result":{"label":"Change Account","item":"address"}}
{"start":false,"result":{"label":"Close Account","item":"account"}}

I am trying to deserialize some json exported from Splunk. The data does not look like an array, but rather a list of json objects between {}. Here are the first three objects of 600 so you can see the format. The first one is actually the Splunk output. I shortened the "Search" in the next two.

{"preview":false,"result":{"label":"Internal Admin Nav","search":"<view isVisible=\"false\" >\n  <label>Internal Admin Nav<\/label>\n  <module name=\"Message\" layoutPanel=\"messaging\">\n    <param name=\"filter\">*<\/param>\n    <param name=\"clearOnJobDispatch\">False<\/param>\n    <param name=\"maxSize\">1<\/param>\n  <\/module>\n  <module name=\"AccountBar\" layoutPanel=\"appHeader\">\n    <param name=\"mode\">lite<\/param>\n  <\/module>\n  <module name=\"LiteBar\" layoutPanel=\"liteHeader\"><\/module>\n<\/view>"}}    
{"preview":false,"result":{"label":"Setup Account","search":"AAAA"}}    
{"preview":false,"result":{"label":"Contactless Dashboard","search":"BBBB"}}

If I try to create a class by pasting the first three lines into Visual Studio using Paste Special|Paste JSON as Classes, it complains that it is not Json data (Notepad seems to think it is though). If I just paste one of them {"preview":false,"result":{"label":"Contactless Dashboard","search":"BBBB"}} I get this object:

public class Rootobject
{
   public bool preview { get; set; }
   public Result result { get; set; }
}

public class Result
{
    public string label { get; set; }
    public string search { get; set; }
}

I have tied to deserialize in many ways.

Rootobject jsonObj = JsonConvert.DeserializeObject<Rootobject>(File.ReadAllText(fileName));

Error: Additional text encountered after finished reading JSON content:

List<Rootobject> jsonObj = JsonConvert.DeserializeObject<List<Rootobject>>(File.ReadAllText(fileName));

Error: Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[ChecSourcetypes.Program ObjClass]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.

To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path 'preview', line 1, position 11.'

This is the most promising one and I tried to force it to deserialize by using a JsonObjectAttribute, but that just raised more problems.

I also added this class

public class RootRootobject 
{
   public List<Rootobject> objects { get; set; }
}

and then used this:

RootRootobject jsonObj = JsonConvert.DeserializeObject<RootRootobject>(File.ReadAllText(fileName));

I have messed with List<> and different objects without any success. I even converted the data to look like this:

[{"preview":false,"result":{"label":"Internal Admin Nav","search":"CCC"}},
{"preview":false,"result":{"label":"Setup Account","search":"AAAA"}},
{"preview":false,"result":{"label":"Contactless Dashboard","search":"BBBB"}}]

How do I read this json into an object? I would not want to change the Splunk output, but I could. I also would like to do it using JsonConvert.DeserializeObject. I recall doing this with Splunk data a few years ago using List<>, but do not remember how.

Thanks.

CodePudding user response:

{"start":true,"result":{"label":"Setup Account","item":"name"}}
{"start":false,"result":{"label":"Change Account","item":"address"}}
{"start":false,"result":{"label":"Close Account","item":"account"}}

This is not valid json as a whole. Each line individually is valid, so you would need deserialize line by line and then add each resulting RootObject to a List<RootObject> as you loop through the lines.

[{"preview":false,"result":{"label":"Internal Admin Nav","search":"CCC"}},
{"preview":false,"result":{"label":"Setup Account","search":"AAAA"}},
{"preview":false,"result":{"label":"Contactless Dashboard","search":"BBBB"}}]

This is valid json, but instead of desrializing to RootRootobject with the List<RootObject> member, you should just deserialize to List<RootObject>

However, your model doesn't match your data, so you need to fix that too. For each object in this data, you have a bool, and a list of another object with 2 strings.

public class Rootobject
{
   public bool preview { get; set; }
   public List<Result> result { get; set; }
}

public class Result
{
    public string label { get; set; }
    public string search { get; set; }
}

CodePudding user response:

you have to fix your json to this (actually your last case)

[{"preview":false,"result":{"label":"Internal Admin Nav","search":"CCC"}},
{"preview":false,"result":{"label":"Setup Account","search":"AAAA"}},
{"preview":false,"result":{"label":"Contactless Dashboard","search":"BBBB"}}]

use your first classes

public class Rootobject
{
   public bool preview { get; set; }
   public Result result { get; set; }
}

and this code

List<RootRootobject> jsonObj = JsonConvert.DeserializeObject<List<RootRootobject>>(yourFixedJson);
  • Related