0

I exported from Azure IoT Central to a Blob Storage a file containing several JSON objects (36 objects) within that same file.

The below are the first 2 lines from that file

{"applicationId":"appID","component":"thermostat1","deviceId":"usingTemControllerTemplate","enqueuedTime":"2022-03-21T15:31:38.687Z","enrichments":{},"messageProperties":{},"messageSource":"telemetry","schema":"default@v1","telemetry":{"temperature":23.2},"templateId":"urn:modelDefinition:tczx6jwcwz1:h2httvyo48g"}

{"applicationId":"appID","component":"thermostat2","deviceId":"usingTemControllerTemplate","enqueuedTime":"2022-03-21T15:31:38.703Z","enrichments":{},"messageProperties":{},"messageSource":"telemetry","schema":"default@v1","telemetry":{"temperature":16.9},"templateId":"urn:modelDefinition:tczx6jwcwz1:h2httvyo48g"}

I created 2 classes to show the heirarchy in the JSON objects. RootObject & Telemetry.

public class RootObject
{
    public string applicationId { get; set; }
    public string component { get; set; }
    public string deviceId { get; set; }
    public string enqueuedTime { get; set; }
    public string messageSource { get; set; }
    public string schema { get; set; }
    public List<Telemetry> telemetry { get; set; }
    public string templateId { get; set; }
}

public class Telemetry
{
    public double temperature { get; set; }
}

I followed this answer and modeled it to my specific heirarchy and tried to make it work. However, a JsonReaderException is being thrown I run it in Visual Studio. This is the code I'm running:

using Newtonsoft.Json;

string filePath = "~pathToFile";
RootObject rt = JsonConvert.DeserializeObject<RootObject>(filePath);

if (rt.telemetry[1].temperature == 23.2)
{
    Console.WriteLine(rt.telemetry[1].temperature);
}

The JsonReaderException is being thrown on this line:

RootObject rt = JsonConvert.DeserializeObject<RootObject>(filePath);

In the below image is the message being shown: JsonReaderException thrown

Could someone please help me find the cause of this issue and how I could resolve it?

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
J.Z
  • 33
  • 1
  • 6

3 Answers3

1

This file is not a list/array of objects, it's a 36 lines with each line containing json for a single object.

With this observation we can:

List<RootObject> list = new();
foreach(var line in lines.Where( l => !string.IsNullOrWhiteSpace(l)))
{
   RootObject? o = JsonConvert.DeserializeObject<RootObject>(line);
   if (o != null)
   {
     list.Add(o); 
   }
}

telmetry is an object, not a list so you need to also change the RootObject definition:

    "telemetry": {
        "temperature": 23.2
    },
public class RootObject
{
    ...
    public Telemetry telemetry { get; set; }
tymtam
  • 31,798
  • 8
  • 86
  • 126
  • Hello. It is still giving me the same exception. "Error parsing comment. Expected: *, got U. Path '', line 1, position 1." – J.Z Mar 28 '22 at 10:27
  • OK, I had an obvious error there. The read should be from `(line)`. I also added some defensives. – tymtam Mar 28 '22 at 10:57
  • Ohh I also didn't notice that 'line' wasn't used. It worked! Thank you so much! – J.Z Mar 28 '22 at 13:00
0

first of all the JSON format is wrong, it looks like this (see below) and secondly he doesn't want to have the File path but the json (value), so you have to read it in and what is also very important. You have 2 elements of "RootObject", that means you have to put into a Array or List<> of RootObjects

Code:

using Newtonsoft.Json;

//reads the file and saves into a string
string jsonValue = File.ReadAllText("~pathToFile");

//Deserialize the objects and put them in a list of "RootObject".
List<RootObject> rt = JsonConvert.DeserializeObject<List<RootObject>>(jsonValue);

correct JSON format:

[
     {
          "applicationId": "appID",
          "component": "thermostat1",
          "deviceId": "usingTemControllerTemplate",
          "enqueuedTime": "2022-03-21T15:31:38.687Z",
          "enrichments": {},
          "messageProperties": {},
          "messageSource": "telemetry",
          "schema": "default@v1",
          "telemetry": {
               "temperature": 23.2
          },
          "templateId": "urn:modelDefinition:tczx6jwcwz1:h2httvyo48g"
     },
     {
          "applicationId": "appID",
          "component": "thermostat2",
          "deviceId": "usingTemControllerTemplate",
          "enqueuedTime": "2022-03-21T15:31:38.703Z",
          "enrichments": {},
          "messageProperties": {},
          "messageSource": "telemetry",
          "schema": "default@v1",
          "telemetry": {
               "temperature": 16.9
          },
          "templateId": "urn:modelDefinition:tczx6jwcwz1:h2httvyo48g"
     }
]
Schecher_1
  • 343
  • 4
  • 12
  • Hello. The previous exception has been resolved now but there's a new exception now: "Cannot deserialize the current JSON object (e.g. {\"name\":\"value\"}) into type 'System.Collections.Generic.List`1[RootObject]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.\nTo 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. – J.Z Mar 28 '22 at 11:06
  • [Continuation of the exception]: JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.\nPath 'applicationId', line 1, position 17." – J.Z Mar 28 '22 at 11:07
  • Has the error been corrected because above there is already a correct answer? – Schecher_1 Mar 29 '22 at 12:21
0

you have to fix json, by converting it to array of objects

    var json = File.ReadAllText(filePath);
    json = "[" + json.Replace("\n\r",",")+"]";

    List<RootObject> lrt = JsonConvert.DeserializeObject<List<RootObject>>(json);
    
    double[] telemetries=rt.Select(r => r.telemetry.temperature ).ToArray(); // [23.2,16.9]
    
    double telemetry=rt.Where(t=> t.telemetry.temperature==23.2)
                            .Select(r =>r.telemetry.temperature ).FirstOrDefault(); //23.2

and fix class too, telemetry should be an object, not a list

public class RootObject
{
    ....
    public Telemetry telemetry { get; set; }
}
Serge
  • 40,935
  • 4
  • 18
  • 45
  • Hello. The previous exception has been resolved but there's a new exception now: "After parsing a value an unexpected character was encountered: {. Path '[0]', line 2, position 0." – J.Z Mar 28 '22 at 10:48
  • @J.Z I tested the code using a json you posted. It means that you posted a wrong json. Post the real one in other I could correct my code. – Serge Mar 28 '22 at 11:26