deserializing json to c# object - c#

my C# is not well but I want to deserializing this my json file to C# object:
[
{
"command":"",
"name":"eee",
"children":
[
{
"command":"Report",
"name":"x",
"children":[],
"path":"wwwwww",
"params":
{
"PeriodType":"1i",
"District":"0i"
}
},...
],
"path":"",
"params":{}
},...
for this schema I have created this object:
[DataContract]
public class ListCommands
{
[DataMember]
public List<Commands> commandList { get; set; }
[DataContract]
public class Commands
{
[DataMember]
public string command { get; set; }
[DataMember]
public string name { get; set; }
[DataMember]
public string path { get; set; }
[DataMember(Name = "params")]
public Params parameters { get; set; }
[DataMember]
public List<Commands> children { get; set; }
}
}
}
and :
public class Params
{
[DataMember]
public string PeriodType { get; set; }
[DataMember]
public string District { get; set; }
}
}
and I am using this code for deserializing json to c# object:
public static void ReadJsonFile()
{
ListCommands comList = new ListCommands();
//List<Commands> comList = new List<Commands>();
string root = HttpContext.Current.Server.MapPath("~/File");
using (FileStream stream = File.OpenRead(root + "\\commands.json"))
comList = (ListCommands)new DataContractJsonSerializer(typeof(ListCommands)).ReadObject(stream);
}
}
but unfortunately I got this error:
Additional information: There was an error deserializing the object of type Notifications.Contracts.ListCommands. Encountered unexpected character 'ï'.
Where is the problem?I have a json file and I want to read this file and then convert to the c# object.

The data format for deserialization differs.
Change json data.
{
"commandList":[
{
"command":"",
"name":"eee",
"children":
[
{
"command":"Report",
"name":"x",
"children":[],
"path":"wwwwww",
"params":
{
"PeriodType":"1i",
"District":"0i"
}
}
],
"path":"",
"params":{}
}]
}
or 2. Change the deserialization target type
comList.commandList = (List<ListCommands.Commands>)new DataContractJsonSerializer(typeof(List<ListCommands.Commands>)).ReadObject(stream);

According suggestion of #SirRufo
1- I have used of Json.Net in this way:
string root = HttpContext.Current.Server.MapPath("~/File");
FileStream stream = File.OpenRead(root + "\\commands.json");
StreamReader reader = new StreamReader(stream);
var comList = JsonConvert.DeserializeObject<dynamic>(reader.ReadToEnd());
and above error gone.
2- By this link I could run previously code:
enter link description here
One of the reasons for this could be that the input file that contains the JSON-encoded data is created with a binary encoding or it has a Byte Order Mark(BOM) byte sequence for a binary encoded file.
For e.g. The UTF-8 representation of the BOM is the byte sequence (0xEF,0xBB,0xBF) in the beginning of the file.
**Note:** You will see this if you created a .JSON file(or a binary file) using visual studio.

Related

JsonReaderException being throw trying to parse a JSON file that contains several JSON objects inside [C#]

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:
Could someone please help me find the cause of this issue and how I could resolve it?
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; }
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"
}
]
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; }
}

c# json get only array from json results

I am new to c# json.
I would only want to get CardTransactions array , "status": 0, and ignore the rest of the json values.
May I know how to achieve with c#.
{
"response":{
"timeStamp":7812371,
"totalCount":1,
"CardTransactions":[
{
"transactionDate":"2021-08-16",
"invoiceNo":"KM011782313",
"amount":2000.00
}
],
"status":0,
"message":"dakjalsda"
},
"status":null,
"message":null
}
Create a model class that looks that way
public class Response
{
[JsonProperty("CardTransactions")]
public List<CardTransaction> CardTransactions { get; set; }
[JsonProperty("status")]
public int Status { get; set; }
}
public class Root
{
[JsonProperty("response")]
public Response Response { get; set; }
}
and use Newtonsoft to convert JSON to object like the following
Root response = JsonConvert.DeserializeObject<Root>(yourJson);

c# data pull from json - can not detect the "-" sign between words

string json_index = '"libraries": [
{
"name": "test1",
"natives": {
"windows": "natives-windows"
},
"downloads": {
"classifiers": {
"natives-windows": {
"url": "http://test1.com/"
}
}
}
},
{
"name": "test2",
"natives": {
"windows": "natives-windows"
},
"downloads": {
"classifiers": {
"natives-windows": {
"url": "http://test2.com/"
}
}
}
}
]';
dynamic jsonObj = JsonConvert.DeserializeObject(json_index);
foreach (var obj in jsonObj.libraries)
{
label1.Text += "\n" + obj.downloads.classifiers.natives-windows.url; // error here
}
Can not detect the "-" sign between words.
I actually thought that:
string nativeswindows = obj.natives.windows;
label1.Text += "\n" + obj.downloads.classifiers.nativeswindows.url;
but it did not work
How can I get the "url" in "natives-windows" ?
I am using Newtonsoft JSON.
you try:
label1.Text += "\n" + obj.downloads.classifiers["natives-windows"].url;
I found this link: Parsing JSON w/ # at sign symbol in it (arobase)
Hope it will help you!
So there's a few steps to this.
First you need to define a concrete class to represent your JSON. I've done this using http://json2csharp.com, with the output being here:
public class Natives
{
public string windows { get; set; }
}
public class NativesWindows
{
public string url { get; set; }
}
public class Classifiers
{
public NativesWindows __invalid_name__natives-windows { get; set; }
}
public class Downloads
{
public Classifiers classifiers { get; set; }
}
public class Library
{
public string name { get; set; }
public Natives natives { get; set; }
public Downloads downloads { get; set; }
}
public class RootObject
{
public List<Library> libraries { get; set; }
}
Your problematic field has been flagged up by this tool too, seen here:
public NativesWindows __invalid_name__natives-windows { get; set; }
So we need a way to assign the JSON Key/Value pair to a valid C# field. We can does this using Attributes.
For this field in particular, we can use the JsonProperty attribute to take in the JSON property name and assign it to a C# field on your new concrete class. This looks like:
[JsonProperty("native-windows")]
public NativesWindows NativeWindowsObj { get; set; }
You can put that into your new concrete class, and then use the following to deserialize to that type:
Natives jsonObj = JsonConvert.DeserializeObject<Natives>(json_index);
This is telling Newtonsoft:
I have a property name native-windows.
I'm deserializing my JSON to this specific class.
The invalid C# identified native-windows matches a JsonProperty I've specified in my class, assign the value to that matching attribute.
Return the full, deserialized object.

Deserialize Json from file in C#

I've managed to find a solution without removing the paths from the keys.Thanks for the help guys, and also pointing out problems, I really appreciate it! :)
Loaded the Json to a string, deserialized it into a dynamic, ran a foreach through it, and added to a List with ResFiles in it.
static void loadJson()
{
List<ResFile> fileList = new List<ResFile>();
string jsonString = File.ReadAllText(jsonPath);
dynamic files = JsonConvert.DeserializeObject(jsonString);
foreach (var f in files.objects)
fileList.Add(new ResFile(f.Name, f.Value.hash.ToString(), (int)f.Value.size.Value));
}
I'm trying to deserialize some Json file in C# with Newtonsoft's Json library.
The files are named after it's hash, not the real file name and I want to rename them back to the proper names, so like this:
10a54fc66c8f479bb65c8d39c3b62265ac82e742 >> file_1.ext
The Json file:
{
"files": {
"file_1.ext": {
"hash": "10a54fc66c8f479bb65c8d39c3b62265ac82e742",
"size": 8112
},
"file_2.ext": {
"hash": "14cfb2f24e7d91dbc22a2a0e3b880d9829320243",
"size": 7347
},
"file_3.ext": {
"hash": "bf7fadaf64945f6b31c803d086ac6a652aabef9b",
"size": 3838
},
"file_4.ext": {
"hash": "48f7e1bb098abd36b9760cca27b9d4391a23de26",
"size": 6905
}
}
}
I've tried deserialize with this:
static void loadJson()
{
using (StreamReader reader = new StreamReader(jsonPath))
{
string json = reader.ReadToEnd();
dynamic files = JsonConvert.DeserializeObject(json);
}
}
The deserialization itself working, but I don't know how to loop through them.
I've also tried to do this:
class ResFile
{
public string name;
public string hash;
public int size;
}
And somehow force the deserialization to use this, but it didn't work of course.
According to your sample json, your classes would be:
public class ResFile
{
public string hash { set; get; }
public int size { set; get; }
}
public class ResRoot
{
public Dictionary<string, ResFile> Files { set; get; }
}
You can deserialize as
var res = JsonConvert.DeserializeObject<ResRoot>(File.ReadAllText(filename));
foreach(var f in res.Files)
{
Console.WriteLine("Name={0} Size={1}", f.Key, f.Value.size);
}
Please follow the C# conventions and do not expose member variables as public or start property names with lower case. In order to make your conventional objects deserializable, you could use the System.Runtime.Serialization DataContract and DataMember attributes. DataContract indicates that an object of this type is serializable and DataMember is used to specify a property's serialization name.
class ResFile
{
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "hash")]
public string Hash { get; set; }
[DataMember(Name = "size")]
public int Size { get; set; }
public ResFile () { }
}
[DataContract]
class ResFileCollection
{
[DataMember(Name ="files")]
public Dictionary<string, ResFile> Files { get; set; }
}
And here is the deserialization:
string json = File.ReadAllText("data.json");
var files = JsonConvert.DeserializeObject<ResFileCollection>(json);
foreach(KeyValuePair<string, ResFile> f in files.Files)
{
Console.WriteLine("{0} {1} {2}", f.Key, f.Value.Name, f.Value.Hash);
}
Serialized property names should also be shorter for better performance. An example:
[DataMember(Name="src")]
public string SourcePath { get; set; }

write data from JSON in C#

I have JSON like this:
{
'surveys': [
{
'title': 'first',
'id': 100,
},
{
'title': 'second',
'id': 101,
},
{
'title': 'third',
'id': 102,
},
]
}
I want to have the output like this:
title: first
title: second
title: third
and my program in C# is like this:
WebClient client = new WebClient();
var json = client.DownloadString("http://www.test.com/api/surveys/?api_key=123");
Debug.WriteLine(json); //write all data from json
//add
var example = JsonConvert.DeserializeObject<Example>(json);
Debug.WriteLine(example.Data.Length);
class Example
{
public surveys[] Data { get; set; }
}
class surveys
{
public string title { get; set; }
public int id { get; set; }
}
I get this error:
Thrown: "Object reference not set to an instance of an object." (System.NullReferenceException) Exception Message = "Object reference not set to an instance of an object.", Exception Type = "System.NullReferenceException", Exception WinRT Data = ""
at this line: Debug.WriteLine(example.Data.Length);
where is the problem?
One problem I see is that your outer class has a property named Data, which is an array of 'surveys' objects, but your Json has a list of 'surverys' objects under the property 'surveys'. Hence the 'Data' property is never populated.
Consider the following C# class structure:
class Example
{
public survey[] surveys{ get; set; }//Data renames to surveys
}
class survey //Singular
{
public string title { get; set; }
public int id { get; set; }
}
Why can't you do so?:
JObject data = JObject.Parse(json);
foreach (var survey in data["surveys"].Children())
{
Debug.WriteLine("title: " + survey["title"]);
}
You need to use JSON.Net and use the class JsonConvert and the method DeserializeObject<T>.
If you run this:
JsonConvert.DeserializeObject<JObject>();
Then you will get back a list of de-serialized JObject objects.
Use, NuGet to download the package. I think it is called JSON.net.
Here is the weblink
WebClient client = new WebClient();
var json = client.DownloadString("http://www.test.com/api/surveys/?api_key=123");
Debug.WriteLine(json); //write all data from json
//add
var example = JsonConvert.DeserializeObject<Survey>(json);
Debug.WriteLine(example.length); // this could be count() instead.
class Survey
{
public string title { get; set; }
public int id { get; set; }
}
This should work!
Use json2csharp to generate c# classes from json.
You will also need to use Json.NET.
public class Survey
{
public string title { get; set; }
public int id { get; set; }
}
public class RootObject
{
public List<Survey> surveys { get; set; }
}
Then you can do:
var client = new WebClient();
string json = client.DownloadString(some_url);
RootObject root = JsonConvert.DeserializeObject<RootObject>(json);
foreach (Survey s in root.surveys)
{
// Do something with your survey
}
Don't forget to use Newtonsoft.Json namespace once you add a reference to it within your project.
using Newtonsoft.Json;
Edit: I have tested it using:
string json = "{'surveys': [{'title': 'first','id': 100,},{'title': 'second','id': 101,},{'title': 'third','id': 102,},]}";
instead of using the WebClient, and it works.

Categories