1

First off, I do not have much experience with Json.Net, so I apologize in advance. I can deserialize basic objects just fine, but here is where I'm having troubles...

I have this crazy return JSON which I have no idea how to deserialize. I have pasted it below. I am using C# and the Newtonsoft.Json (Json.Net) NuGet package to write an application to consume this JSON.

Basically, the JSON is split up by "Type" (either "D", "M", "O", "R", "G", or "A") and that type has a nested JSON object ("IO") with a bunch of relevant information about the type status. The IO data is a List.

[
   {
      "Type":"D",
      "IO":[
         {
            "#":1,
            "Desc":"Level",
            "SC":583,
            "DT":"Tuesday - 4/8/14 at 5:03 AM",
            "InAlarm":false
         },
         {
            "#":2,
            "Desc":"Input 2 ",
            "SC":348,
            "DT":"Tuesday - 4/8/14 at 8:05 AM",
            "InAlarm":false
         },
         {
            "#":3,
            "Desc":"Input 3 ",
            "SC":214,
            "DT":"Tuesday - 4/8/14 at 9:05 AM",
            "InAlarm":false
         },
         {
            "#":4,
            "Desc":"Input 4 ",
            "SC":180,
            "DT":"Tuesday - 4/8/14 at 6:24 AM",
            "InAlarm":false
         },
         {
            "#":8,
            "Desc":"Input 8 ",
            "SC":296,
            "DT":"Tuesday - 9/18/12 at 3:20 PM",
            "InAlarm":false
         },
         {
            "#":9,
            "Desc":"Input 9 ",
            "SC":282,
            "DT":"Tuesday - 9/18/12 at 3:20 PM",
            "InAlarm":false
         },
         {
            "#":10,
            "Desc":"Input 10",
            "SC":406,
            "DT":"Tuesday - 9/18/12 at 3:20 PM",
            "InAlarm":false
         },
         {
            "#":11,
            "Desc":"Input 11",
            "SC":246,
            "DT":"Wednesday - 1/15/14 at 2:36 PM",
            "InAlarm":false
         }
      ]
   },
   {
      "Type":"M",
      "IO":[
         {
            "#":5,
            "Desc":"Input 5 ",
            "VS":"Style: Rain"
         },
         {
            "#":6,
            "Desc":"Input 6 ",
            "VS":"Style: Counter"
         },
         {
            "#":7,
            "Desc":"Input 7 ",
            "VS":"Style: Counter"
         }
      ]
   },
   {
      "Type":"R",
      "IO":[
         {
            "#":12,
            "Desc":"Pump 1 Start Failure",
            "SC":952,
            "DT":"Thursday - 2/6/14 at 11:23 AM",
            "InAlarm":false
         },
         {
            "#":13,
            "Desc":"Pump 2  Start Failure",
            "SC":960,
            "DT":"Thursday - 2/6/14 at 12:06 PM",
            "InAlarm":false
         },
         {
            "#":14,
            "Desc":"high level Start Failure",
            "SC":936,
            "DT":"Thursday - 2/6/14 at 12:49 PM",
            "InAlarm":false
         }
      ]
   },
   {
      "Type":"G",
      "IO":[
         {
            "Desc":"Primary Power",
            "SC":28,
            "DT":"Tuesday - 4/8/14 at 7:04 AM",
            "InAlarm":false,
            "VS":"Present"
         },
         {
            "Desc":"Battery Status",
            "SC":26,
            "DT":"Monday - 4/7/14 at 12:05 PM",
            "InAlarm":false,
            "VS":"13.25 Volts"
         },
         {
            "Desc":"Signal Strength",
            "SC":2,
            "DT":"Wednesday - 4/2/14 at 6:21 AM",
            "InAlarm":false,
            "VS":"-70 db"
         },
         {
            "Desc":"Maintenance Key",
            "SC":12,
            "DT":"Thursday - 4/3/14 at 2:00 PM",
            "InAlarm":false,
            "VS":"Enabled"
         },
         {
            "Desc":"Communication Check",
            "SC":49,
            "DT":"Thursday - 4/3/14 at 5:02 AM",
            "InAlarm":false,
            "VS":"State Change"
         }
      ]
   },
   {
      "Type":"A",
      "IO":[
         {
            "#":1,
            "Desc":"Analog 1",
            "SC":568,
            "DT":"Tuesday - 4/8/14 at 9:24 AM",
            "InAlarm":0,
            "VS":"6.60 ft"
         },
         {
            "#":2,
            "Desc":"Analog 2 ",
            "SC":8,
            "DT":"Thursday - 6/10/10 at 2:15 PM",
            "InAlarm":0,
            "VS":"13.00 ft"
         },
         {
            "#":3,
            "Desc":"Analog 3 ",
            "SC":12,
            "DT":"Monday - 6/21/10 at 11:20 AM",
            "InAlarm":0,
            "VS":"13.00 ft"
         },
         {
            "#":4,
            "Desc":"Analog 4 ",
            "SC":4,
            "DT":"Monday - 6/14/10 at 11:11 AM",
            "InAlarm":0,
            "VS":"12.90 ft"
         }
      ]
   },
   {
      "Type":"O",
      "IO":[
         {
            "#":1,
            "Desc":"Output 1",
            "SC":0,
            "DT":"NA",
            "VS":"Automatic"
         },
         {
            "#":3,
            "Desc":"Output 3",
            "SC":0,
            "DT":"NA",
            "VS":"Automatic"
         },
         {
            "#":2,
            "Desc":"Output 2",
            "SC":0,
            "DT":"NA",
            "VS":"Automatic"
         },
         {
            "#":4,
            "Desc":"Output 4",
            "SC":0,
            "DT":"NA",
            "VS":"In Hand - Off"
         }
      ]
   }
]

I want to have an object called Status which will contain fields for each "Type" (D, M, O, R, G, or A). See below for my example class, where the "D" type is a Digital class and the "M" type is a Monitoring class.

public class Status
{
     public ObservableCollection<Digital> Digital {get;set;}
     public ObservableCollection<Monitoring> Monitoring{get;set;}
     etc....
}

public class Digital
{
     // I'll replace the # in the JSON with "number" or something
     // before deserializing
     public string # {get;set;}
     public string Desc {get;set;}
     public string Ss {get;set;}
     public string Dt {get;set;}
     public string InAlarm {get;set;}
}

I then want access to the nested objects, by doing something like this. In this example, I want the "D" JSON type, and the data for "IO" #1:

var _statusObjMagic = new Status();
// Go get the JSON and deserialize it.. build up the _statusObjMagic 
Some magical code here...

// Get some data from the JSON response
string inputOneDescription = _statusObjMagic.Digital[0].Desc;

What is the easiest way to deserialize this JSON and get the above results? Maybe I am going about this wrong and there is an easier way to deserialize the JSON and get access to all of the data. I am totally open.

1
  • Are you creating that JSON? If not, where is it coming from? Although technically valid JSON, it doesn't make any sense Commented Apr 8, 2014 at 14:26

1 Answer 1

3

You need to have a proper class to deserialize to.

I used JSON 2 C# to generate one for you.

public class IO
{
    [JsonProperty(PropertyName = "#")]
    public int Id{ get; set; }
    public string Desc { get; set; }
    public int SC { get; set; }
    public string DT { get; set; }
    public object InAlarm { get; set; }
    public string VS { get; set; }
}

public class RootObject
{
    public string Type { get; set; }
    public List<IO> IO { get; set; }
}

In C#, # is not a valid property name. So I used the JSON Property Attribute provided by Json.NET to tell Json.NET how to convert it.

Then you can deserialize.

List<RootObject> mylist = JsonConvert.DeserializeObject<List<RootObject>>(json);
Sign up to request clarification or add additional context in comments.

5 Comments

That was my first attempt and no luck. The problem is, the root object type contains a string named Type and a List IO. The IO list does not contain the same parameters on each type (i.e., the "D" type IO list doesn't have the same schema as the "M" type IO list).
{Newtonsoft.Json.JsonSerializationException: Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Testing.Models.Status' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly. To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List<T> that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
I think the error message is pretty clear. Instead of your JSON representing a single object, it represents a array of objects. So your deserialized type should be probably be a Generic List such as List<Status>.
Thank you! I appreciate the time you took to help me out!
No problem. The trick is figure out what you need to deserialize to. Making sure you have valid JSON and using a tool to help you generate the C# class goes a long way towards that. I only started using JSON and Json.NET a few months ago, but have found that it's invaluable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.