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

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);
}

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);
}

Related

How to parse unreadable json?

{
"12": {
"_agicId": 2,
"_index_": "",
"_seq": 1
},
"11": {
"_agicId": 1,
"_index_": "",
"_seq": 2
},
"10": {
"_agicId": 0,
"_index_": "",
"_seq": 3
}
}
I get a json string like above, but i don't know "12""11""10", how can i parser this json get _seq & agicId?
var Name = JObject.Parse(r);
int Count = Name.Count;
for (int i = 0; i < Name.Count; i++)
{
// how can i get "11"{"agicId":0}
}
For this create a model class like below:
class Test
{
public int _agicId { get; set; }
public string _index_ { get; set; }
public string _seq { get; set; }
}
And then read the json like below. I have read from file . you can read from string also. In the key you will get 11, 12 etc...and in value you will get the Text class having values for "agicId" etc...
using (StreamReader r = new StreamReader("data.json"))
{
string jsonString = r.ReadToEnd();
JObject jsonObj = JObject.Parse(jsonString);
var k = JsonConvert.DeserializeObject<Dictionary<string, Test>>(jsonString);
/*
A very good suggestion by Jon Skeet. No need of this foreach loop. Instead of criticising he has suggested a better solution.
foreach(var item in jsonObj)
{
string key = item.Key;
var value = JsonConvert.DeserializeObject<Test>(item.Value.ToString());
}*/
}

Parse JSON String into List

It is needed to parse JSONString into List. (List of instances)
I'm trying to use JSON.NET by Newtonsoft.
I have classes:
public class Item
{
public int ID { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public string Manufactorers { get; set; }
}
The JSON string looks something like this:
[
{
"Column0":23.0,
"Column1":"Евроен",
"Column2":"https://www.123.com",
"Column3":"Фак"
},
{
"Column0":24.0,
"Column1":"Еил",
"Column2":"https://www.123.com",
"Column3":"Старт"
}
]
I've been trying to do something like this:
string JSONString = string.Empty;
JSONString = JsonConvert.SerializeObject(result);
List<Item> items = JsonConvert.DeserializeObject<List<Item>>(JSONString);
But it returns 0 and null.
I have no idea, how to fix it.
Also here I truy to parse Excel file. This code works, but after deserialization, I have just 0 and null.
var filePath = #"..\..\..\..\doc.xlsx";
using (var steam = File.Open(filePath, FileMode.Open, FileAccess.Read))
{
using (var reader = ExcelReaderFactory.CreateReader(steam))
{
var result = reader.AsDataSet().Tables["Лист1"];
string JSONString = string.Empty;
JSONString = JsonConvert.SerializeObject(result);
List<Item> items = JsonConvert.DeserializeObject<List<Item>>(JSONString);
}
}
The naming of JSON and your class does not match. This can be fixed using JsonProperty attributes:
[JsonProperty("Column0")]
public decimal ID { get; set; }
Second, JSON deserizlizer can not deserialize string "23.0" to int when there is decimal point. You can retype ID to decimal or double to make it work.
Little test here:
public class TestClass
{
[JsonProperty("Column0")]
public decimal ID { get; set; }
}
Then the deserialization works without errors:
var testClassJson = "{\"Column0\": 12.0}";
var i = JsonConvert.DeserializeObject<TestClass>(testClassJson);

C# JSON Serialize/Deserialize - INPUT problem

I have problem with serialization and deserialization in JSON
I've made 2 tasks to read from JSON file which looks like this:
[
{
"ID": 1,
"OIB": 123456789,
"ime": "name",
"prezime": "surname",
"grad": "city"
}
]
Now I have to add another client with ID 2, with new user informations.
I can read this JSON file with no problems, but I am stuck on writing into the same file.
public struct Klijent
{
public int ID { get; set; }
public long OIB { get; set; }
public string ime { get; set; }
public string prezime { get; set; }
public string grad { get; set; }
}
"FetchClient" from JSON
public static List<Klijent> DohvatiKlijente()
{
List<Klijent> lKlijent = new List<Klijent>();
StreamReader klijent = new StreamReader("x");
string sJson = "";
using (klijent)
{
sJson = klijent.ReadToEnd();
lKlijent = JsonConvert.DeserializeObject<List<Klijent>>(sJson);
}
return lKlijent;
}
"AddClient" to JSON
OIB -> personal identificator
ID -> should go +1 with every entry of client
grad -> city
ime -> name
prezime -> surname
public static void DodavanjeKlijenata()
{
Console.Write("Unesite OIB klijenta: ");
string pOIB = Console.ReadLine();
long nullOIB = 0;
long.TryParse(pOIB, out nullOIB);
int id = 0;
Console.Write("Unesite ime klijenta: ");
string ime1 = Console.ReadLine();
Console.Write("Unesite prezime klijenta: ");
string prezime1 = Console.ReadLine();
Console.Write("Unesite grad klijenta: ");
string grad1 = Console.ReadLine();
List<Klijent> lKlijent = DohvatiKlijente();
foreach (var Klijent in lKlijent)
{
id = Klijent.ID + 1;
}
Klijent dKlijent = new Klijent()
{
ID = id,
OIB = nullOIB,
ime = ime1,
prezime = prezime1,
grad = grad1
};
var serializer = new JsonSerializer();
using (var sw = new StreamWriter("x"))
using (JsonWriter writer = new JsonTextWriter(sw))
{
serializer.Serialize(writer, dKlijent);
}
}
This code does work, but it seems to delete every time my JSON file and it's format is in one line only, I would like to have it in multiple lines.
Thank you :)
There are two things that you need to do here
Ensure new Client is appended to existing list
For this you can add the new client to the List
lKlijent.Add(dKlijent);
Now you need to serialize the List, instead of lKlijent
using (JsonWriter writer = new JsonTextWriter(sw))
{
serializer.Serialize(writer, lKlijent);
}
Formatting
For formatting you can use Formatting Settings. For example,
var serializer = new JsonSerializer() { Formatting = Formatting.Indented} ;
Additional Comments
1. Calculation of ID
Instead of calculating the new ID using the following loop,
foreach (var Klijent in lKlijent)
{
id = Klijent.ID + 1;
}
You could use Enumerable.Last() to get the last client in the list. For example,
var id = lKlijent?.Any()!=true? 0:lKlijent.Last().ID;
2. Rewriting DohvatiKlijente method
The DohvatiKlijente method could rewritten as
public static List<Klijent> DohvatiKlijente()
{
return JsonConvert.DeserializeObject<List<Klijent>>(File.ReadAllText("C:\\Users\\Hrvoje\\Desktop\\Polica Osiguranja MAIN\\Polica Osiguranja\\klijent.json"));
}
Similarly, writing back to file can be simplified as
var jsonString = JsonConvert.SerializeObject(lKlijent,Newtonsoft.Json.Formatting.Indented);
File.WriteAllText(outputFilePath,jsonString);

How do I parse only value in json file

From this code. I want to parse only value from the json file
if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
using (StreamReader file = File.OpenText(openFileDialog1.FileName))
using (JsonTextReader reader = new JsonTextReader(file))
{
while (reader.Read())
{
if (reader.Value != null)
{
richTextBox1.Text = reader.Value.ToString();
}
else
{
MessageBox.Show("Error while parsing json file. Please try again.");
}
}
}
}
And the value is
{
"install.and": "a",
"install.emailAddress": "E-mailová adresa",
"install.emailIncorrect": "Zadejte platnou e-mailovou adresu.",
"install.emailRetryPrefix": "Neobdrželi jste e-mail? Zkuste to znovu",
"install.emailRetry": "Zkuste to znovu",
"install.emailSend": "Odeslat odkaz",
"install.emailSent": "E-mail byl odeslán!",
"install.emailSentTo": "E-mail byl odeslán",
"install.emailText1": "Můžete navštívit",
"install.emailText2": "Pokud nám poskytnete e-mailovou adresu, budeme vám moci poslat odkaz na pozdější instalaci.",
"install.installing": "Instalace...",
"install.later": "Instalovat později",
"install.licenseAgreement": "licenční smlouva",
"install.privacyPolicy": "zásady ochrany osobních údajů",
"install.quit": "Ukončit instalační program"
}
I want to parse it after : symbol. (Is it value?) to show in richTextbox as Text.
Try this code
using (StreamReader file = File.OpenText(openFileDialog1.FileName))
using (JsonTextReader reader = new JsonTextReader(file))
{
var o = JObject.Load(reader);
foreach (var v in o)
{
var value = v.Value.Value<string>();
//do whatever you want with value
}
}
If you want only values joined by newline, then try this one
using (StreamReader file = File.OpenText(openFileDialog1.FileName))
using (JsonTextReader reader = new JsonTextReader(file))
{
var o = JObject.Load(reader);
var e = o.Values().Select(x => x.Value<string>());
var values = string.Join(Environment.NewLine, e);
//do whatever you want with values
}
Introduce two temporary variable to hold key and value
string key = string.Empty;
string value = string.Empty;
Modify your while loop like this,
using (JsonTextReader reader = new JsonTextReader(file))
{
while (reader.Read())
{
if (reader.Value != null)
{
key = reader.Value.ToString();
if (reader.Read())
value = reader.Value.ToString();
Console.WriteLine("{0} : {1}", key,value);
//Instead of writing in a console, process and write it in Rich text box.
}
}
}
You can use Json.Net and create a model :
public class JsonObject
{
[JsonProperty("install.and")]
public string install_and { get; set; }
[JsonProperty("install.emailAddress")]
public string emailAddress { get; set; }
[JsonProperty("install.emailIncorrect")]
public string emailIncorrect { get; set; }
[JsonProperty("emailRetryPrefix")]
public string emailRetryPrefix { get; set; }
[JsonProperty("install.emailRetry")]
public string emailRetry { get; set; }
[JsonProperty("install.emailSend")]
public string emailSend { get; set; }
[JsonProperty("install.emailSent")]
public string emailSent { get; set; }
[JsonProperty("install.emailSentTo")]
public string emailSentTo { get; set; }
[JsonProperty("install.emailText1")]
public string emailText1 { get; set; }
[JsonProperty("install.emailText2")]
public string emailText2 { get; set; }
[JsonProperty("install.installing")]
public string installing { get; set; }
[JsonProperty("install.later")]
public string later { get; set; }
[JsonProperty("install.licenseAgreement")]
public string licenseAgreement { get; set; }
[JsonProperty("install.privacyPolicy")]
public string privacyPolicy { get; set; }
[JsonProperty("install.quit")]
public string quit { get; set; }
}
Then you can prase you json file:
string json_data = "{\"install.and\": \"a\",\"install.emailAddress\": \"E-mailová adresa\",\"install.emailIncorrect\": \"Zadejte platnou e-mailovou adresu.\",\"install.emailRetryPrefix\": \"Neobdrželi jste e-mail? Zkuste to znovu\",\"install.emailRetry\": \"Zkuste to znovu\",\"install.emailSend\": \"Odeslat odkaz\",\"install.emailSent\": \"E-mail byl odeslán!\",\"install.emailSentTo\": \"E-mail byl odeslán\",\"install.emailText1\": \"Můžete navštívit\",\"install.emailText2\": \"Pokud nám poskytnete e-mailovou adresu, budeme vám moci poslat odkaz na pozdější instalaci.\",\"install.installing\": \"Instalace...\",\"install.later\": \"Instalovat později\",\"install.licenseAgreement\": \"licenční smlouva\",\"install.privacyPolicy\": \"zásady ochrany osobních údajů\",\"install.quit\": \"Ukončit instalační program\"";
JsonObject data = JsonConvert.DeserializeObject<JsonObject>(json_data);
richTextBox1.Text = data.emailAddress;
richTextBox2.Text = data.emailIncorrect;
richTextBox3.Text = data.emailRetry;
[...]
First, Install newtonsoft.json from nuget package manager. Add the namespace
using Newtonsoft.Json.Linq;
create a class to easily handle the values.
class Details
{
public string and;
public string EmailAddress;
public string EmailIncorrect;
public string EmailRetry;
public string EmailSend;
public string EmailSent;
}
Then read the file into a string and parse it using JObject.
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
string file = File.ReadAllText(openFileDialog1.FileName);
JObject jo = JObject.Parse(file);
Details dt = new Details();
dt.and = (string)jo["install.and"];
richTextBox1.Text = reader.Value.ToString();
}

Serialise JSON color hex without quotes

So I am sending some values to a javascript array. Currently it is an array called data, that has two elements, value and color, for example:
var data = [{value:226,color:"#FFFFF"},{value:257,color:"#FFFFF"}];
The problem is that color should be color: #FFFFF WITHOUT the &quot surrounding. The C# is as follows:
[JsonObject(MemberSerialization.OptIn)]
public class StatsValues
{
[JsonProperty]
public int value { get; set; }
[JsonProperty]
public string color { get; set; }
}
var values = new List<StudentBrandsApp.Models.StatsValues>();
foreach (DataRow dr in statsDataTable.Rows)
{
values.Add(new StudentBrandsApp.Models.StatsValues() { value = Convert.ToInt32(dr.ItemArray[1].ToString()), color = "#FFFFF" });
}
var serializer = new JsonSerializer();
var stringWriter = new StringWriter();
var writer = new JsonTextWriter(stringWriter);
writer.QuoteName = false;
serializer.Serialize(writer, values);
writer.Close();
var json = stringWriter.ToString();
ViewData["json"] = json;
How do I serialise this so that color excludes the quotes and returns simply the hash value?
Please try your json string to below format:
{
"array": [
{
"value":226,
"color":"#FFFFF"
},
{
"value":226,
"color":"#FFFFF"
}
]
}
or
var data = [{"value":226,"color":"#FFFFF"},{"value":257,"color":"#FFFFF"}];

Categories