I am trying to read 2 json files using StreamReader, parse them as JObjects and then perform a merge. However I have am receiving the following error when StreamReader is called for the second time:
Error reading JObject from JsonReader. Current JsonReader item is not
an object: StartArray. Path '', line 1, position 1.
For the line:
string jsonUpdateFile = updatesr.ReadToEnd();
The code below:
var path = String.Format("{0}json\\data.json", AppDomain.CurrentDomain.BaseDirectory);
string jsonOldFile = new StreamReader(path).ReadToEnd();
var updatepath = String.Format("{0}json\\update.json", AppDomain.CurrentDomain.BaseDirectory);
string jsonUpdateFile = new StreamReader(updatepath).ReadToEnd();
var jsonO = JObject.Parse(jsonOldFile);
var jsonU = JObject.Parse(jsonUpdateFile);
//merge new json into old json
jsonO.Merge(jsonU);
//save to file
FileInfo file = new FileInfo(path);
file.Directory.Create();
string JsonToSave = JsonConvert.SerializeObject(jsonO);
System.IO.File.WriteAllText(#path, JsonToSave);
What I am trying to do with the merge:
var jsonO = [{"id":"1234","name":"Bruce"},{"id":"5678","name":"Clark"}]
var jsonU = [{"id":"1234","name":"Wayne"}]
var merge = [{"id":"1234","name":"Wayne"},{"id":"5678","name":"Clark"}
You can take JArray and add the second Json to First One i.e, Like this one
var jsonO = JArray.Parse(jsonOldFile);
var jsonU = JArray.Parse(jsonUpdateFile);
foreach(JObject innerData in jsonU )
{
jsonO.Add(innerData);
}
In order to Update the other json I think you can try this one i dont know once give it a shot
var jsonO = JArray.Parse(jsonOldFile);
var jsonU = JArray.Parse(jsonUpdateFile);
var item = jsonO.Children<JObject>();
foreach(JObject innerData in jsonU)
{
if(innerData[Id] == item[Id])
{
item[Name] = innerData[Name];
jsonO.Replace(item["Name"]);
//[or]
jsonO.Add(item["Name"});
}
else
{
jsonO.Add(innerData);
}
}
even i'm a newbie if i'm wrong please do correct me happy to learn it ..
var jsonO = JArray.Parse(jsonOldFile);
var jsonU = JArray.Parse(jsonUpdateFile);
Using JArray rather than JObject allows me to read the files in. Merge doesn't work as expected but that's a question for another thread.
By looking at the error stated in question, my guess is that your update.json file is not in a valid json format. Please use http://jsonlint.com/ to validate your json first.
Related
How should I get the value of status key ?
string a = "\"[{\\\"Status\\\":\\\"Passed\\\"}]\""
tried with JObject.Parse and JArray.Parse to deserialize it and fetch the value.
getting error all the time, even if the key is present.
PS: this value is coming directly from the DB, where it is stored as a string.
using System.Text.Json;
string a = "\"[{\\\"Status\\\":\\\"Passed\\\"}]\"";
var json = JsonDocument.Parse(a).RootElement.GetString();
var jDoc = JsonDocument.Parse(json);
var dic = jDoc.RootElement[0].Deserialize<Dictionary<string, string>>();
var status = dic["Status"];
Maybe there is a better solution. But you can remove the / character and split by "
string a = "\"[{\\\"Status\\\":\\\"Passed\\\"}]\"";
var val=a.Replace("\\", "").Split(new string[] { "\"" },
StringSplitOptions.None)[4];
Here is a method can get the value, hope it can give you some help.
using Newtonsoft.Json;
string a = "\"[{\\\"Status\\\":\\\"Passed\\\"}]\"";
var b = JsonConvert.DeserializeObject(a);
var c = JsonConvert.DeserializeObject<Dictionary<string, string>[]>(b.ToString());
I created an ASP.NET Application, where I have to parse a csv file with a json structure.
The csv file itself is structured like:
{"Instance":"abc","Date":"2019-06-03T00:00:02.056Z","Identification":"someFunction","Type":"DurationInMs","Value":"5","iserror":"False""}
I get the jsonCsvData as a string and tried to parse it. Then I want to save some of the elements of this json object into a db.
public IActionResult ReadJsonCsvData(string jsonCsvData)
{
Console.WriteLine("ReadJsonCsvData");
ChartData chartData = new ChartData();
var lines = jsonCsvData.Split("\n");
foreach (var line in lines)
{
var values = JObject.Parse(line);
var first = string.Concat(values["Instance"]); //Output for first: ""
}
}
The problem now is, that the variable first is an empty string. The result should be (like in the json structure example above) "abc".
Thank you in advance!
I don't know if it will help but here is my solution (remove one of " at the end of your Json).
I use the "Jobject" to parse Json as I want. Import this two reference.
using Newtonsoft.Json.Linq;
using Newtonsoft;
Then you have to create your JObject :
JObject o = JObject.Parse(myJsonString);
Then to retrieve specifics data, you just have to search in your object just like you do with a dictionary with key :
instanceFromJson = o["Instance"].ToString;
dateFromJson = o["Date"].ToString;
If you have a table in your "instance" json object you can retrieve all data from this list just like that :
foreach (var item in o["Instance"]["tabFromInstanceObject"])
{
MyList.Add(item);
}
I have the following JSON in a text file which I am trying to parse.
{
"0":[68],
"1":[154,78,61],
"2":[89,132,146],
"3":[],
"4":[77,132,146],
"5":[32,132,50],
"6":[],
"7":[114,118,54,44,72,136,156,134,129,82,43,34,51,93,142,67,47,153,160,73,39,149,107,94,145,29,115,53,83,1,35,56,123,66,90,121,155],
"8":[89,146],
"9":[89,146],
"10":[100,135],
"11":[],
"12":[],
"13",[111,131],
"14":[77,124],
"15":[89,146],
"16":[163,126,122],
"17":[100,126,135],
"18":[32,50],
"19":[163,126,122]
}
The code I have is
var map = new List<Dictionary<int, List<int>>>();
using (var r = new StreamReader(#"C:\Development\phase2\dependencymap.json"))
{
var json = r.ReadToEnd();
map = JsonConvert.DeserializeObject<List<Dictionary<int, List<int>>>>(json);
}
But it doesn't seem to like the format. What am I doing wrong?
The JSON is malformed. Check the following line
"13" , [111,131],
and change it to:
"13" : [111,131],
Try map = JsonConvert.DeserializeObject<List<Dictionary<String, List<int>>>>(json);
Your keys are String, not int.
I'm trying to automate the addition of new objects to an existing JSON file. I looked all around the web but only found adding data and stuff but not a whole object. This is how the file that I want to edit looks:
[
{"id":"123","name":"carl"}
]
and I want to go to
[
{"id":"123","name":"carl"},
{"id":"1234","name":"carl2"}
]
Thank you for all your answers but I don't think everyone completely understands what i mean I have tried some of the answers but then I get this:
[
"{\"id\":\"123\",\"name\":\"carl\"}"
]"{\"id\":\"1234\",\"name\":\"carl2\"}"
and I want everything in between the [].
If you use json.NET you can simply deserialize and serialize the json.
var list = JsonConvert.DeserializeObject<List<Person>>(myJsonString);
list.Add(new Person(1234,"carl2");
var convertedJson = JsonConvert.SerializeObject(list, Formatting.Indented);
Using Json.Net
//load from file
var initialJson = "[{\"id\":\"123\",\"name\":\"carl\"}]";
var array = JArray.Parse(initialJson);
var itemToAdd = new JObject();
itemToAdd["id"] = 1234;
itemToAdd["name"] = "carl2";
array.Add(itemToAdd);
var jsonToOutput = JsonConvert.SerializeObject(array, Formatting.Indented);
//save to file here
Using this method doesn't require strongly typed objects
You could replace this bit:
//load from file
var initialJson = "[{\"id\":\"123\",\"name\":\"carl\"}]";
With
var initialJson = File.ReadAllText(#"c:\myjson.json")
To load the json from a text file
A better performing solution than serializing/deserializing what may be a large file would be to open a FileStream, seek 1 character before the end, then serialize and write your new object into the array, then write a closing bracket. See this question C# How to delete last 2 characters from text file and write into the same line at the end my text?, I'll copy the code here - you already know how to serialize your object and encode it into bytes.
using(var fs = new FileStream("file.json")) {
fs.Seek(-1,SeekOrigin.End);
fs.Write(mySerializedJSONObjAsBytes,0,mySerializedJSONObjAsBytes.Length); // include a leading comma character if required
fs.Write(squareBracketByte, 0, 1);
fs.SetLength(fs.Position); //Only needed if new content may be smaller than old
}
Sorry haven't tested any of that, it's off the top of my head. Pro-tip: wrap FileStream in a StreamWriter so can write strings directly.
You could create a method:
public string AddObjectsToJson<T>(string json, List<T> objects)
{
List<T> list = JsonConvert.DeserializeObject<List<T>>(json);
list.AddRange(objects);
return JsonConvert.SerializeObject(list);
}
Then use it like this:
string baseJson = "[{\"id\":\"123\",\"name\":\"carl\"}]";
List<Person> personsToAdd = new List<Person>() { new Person(1234,"carl2") };
string updatedJson = AddObjectsToJson(baseJson, personsToAdd);
this would be a sample for you:
var list = JsonConvert.DeserializeObject<List<Example>>(json);
Example example = new Example();
example.name = "Product2";
example.id="1";
list.Add(example);
string output = JsonConvert.SerializeObject(list);
public class Example
{
public string id {get;set;}
public string name { get; set; }
}
I have been looking for a solution to this exact question for a week now. I finally figured out how to append it to the existing json array and not add it as a solo object after the array. Make sure you are using WriteAllText and not AppendAllText. Here is what I did:
JArray array = JsonConvert.DeserializeObject<JArray (jsonFile);
JObject obj = new JObject();
obj.Add("ID", "123");
obj.Add("Name", "Brian");
array.Add(obj);
var jsonToOutput = JsonConvert.SerializeObject(array, Formatting.Indented);
File.WriteAllText("fileName.json", jsonToOutput);
I'm trying to string data from this JSON Link Click on Link to view
Using JSON.NET. Im able to Deserialize and string the entire thing. But what I need is just values of below
"Warranty":[
{
"EndDate": "ValueIWant",
"ServiceLevelDescription": "ValueIWant"
},
There should be 4 warranty entries from which I need EndDate & ServiceLevelDescription for all and list it in a Multi Line Text box.
Edited: Final Working code
string Serial = "G88NJX1";
WebClient client = new WebClient();
Stream stream = client.OpenRead("https://api.dell.com/support/v2/assetinfo/warranty/tags.json?svctags=" + Serial + "&apikey=1adecee8a60444738f280aad1cd87d0e");
StreamReader reader = new StreamReader(stream);
var jObject = JObject.Parse(reader.ReadLine());
foreach (var o in jObject["GetAssetWarrantyResponse"]["GetAssetWarrantyResult"]["Response"]["DellAsset"]["Warranties"]["Warranty"])
{
Console.WriteLine("Warranty end date: {0}", (string)o["EndDate"]);
Console.WriteLine("Warranty service level description: {0}", (string)o["ServiceLevelDescription"]);
}
Console.ReadLine();
stream.Close();
You can use json.net to parse the json only, rather than deserialize it, then you can query the parsed data, using linq or otherwise. Details here.
This code snippet works in linqpad to output the two values you want from your example json.
var json = #"{'Warranty':[{'EndDate':'ValueIWant','ServiceLevelDescription':'ValueIWant'}]}";
var j = JObject.Parse(json);
foreach(var o in j["Warranty"])
{
Console.WriteLine("Warranty end date: {0}", (string)o["EndDate"]);
Console.WriteLine("Warranty service level description: {0}", (string)o["ServiceLevelDescription"]);
}