So I have been working on JSON files over the past few days, just to understand how C# can manipulate JSON.
I need some help with adding a property to a JSON file. I have figured out how to edit values through trial and error, however, I had assumed that it would create the path where I access the value. Turns out this isn't the case.
This is what I currently have done with regards to access a values Height and Width, however, there is no "externalSite""Weblogin""window" path within the JSON
string widthBox = Width.Text.ToString();
string heightBox = Height.Text.ToString();
string CustomSizejson = File.ReadAllText(DownloadConfigFilelocation);
JObject CustomSizeobj = JObject.Parse(CustomSizejson);
CustomSizeobj["externalSite"]["webLogin"]["window"] = "height=" + heightBox + ",width=" + widthBox + ",resizable,scrollbars";
string CustomSizenewJson = CustomSizeobj.ToString();
File.WriteAllText(DownloadConfigFilelocation, CustomSizenewJson);
This is pretty much what I want to accomplish and append it to the JSON file
Can someone help me figure this out?
Thanks
You can add property using JObject.Add function. Example:
JObject json = new JObject();
json.Add("property_name", "property_value");
If you want to add something not exactly object but inside some property of it.
You first need to find property itself and use JObject.Add function. Example:
JObject inner_json = (JObject) json["property_name"];
inner_json.Add("inner_property_name","value");
You can try something like:
var input = new JObject();
input.Add("window", "height=300,width=410,resizable,scrollbars");
var obj = new JObject();
obj.Add("webLogin", input);
var obj1 = new JObject();
obj1.Add("externalSite", obj);
For more information:
JObject nested property
Related
I have created an object which contains data I want to insert/append to the data currently sitting in a json file.
I have succeeded in getting to to write the data to the file however it overwrites all the data that was there originally.
What i am trying to do is append this Property to the json file whilst keeping all the original information.
This is what I have done so far:
string widthBox = Width.Text.ToString();
string heightBox = Height.Text.ToString();
string WindowSizejson = File.ReadAllText(DownloadConfigFilelocation);
dynamic WindowSizejsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(WindowSizejson);
JObject windowContent = new JObject(
new JProperty("externalSite",
new JObject(
new JProperty("webLogin",
new JObject(
new JProperty("window", "height=" + heightBox + ",width=" + widthBox + ",resizable,scrollbars")
)
)
)
)
);
This is the data currently in the json file that i need to append the above to.
( have blurred out values due to company security reasons)
You have two choices that I can think of:
1.Read the entire file into an object, add your object, and then
rewrite the entire file (poor performance)
var filePath = #"path.json";
// Read existing json data
var jsonData = System.IO.File.ReadAllText(filePath);
// De-serialize to object or create new list
var SomeObjectList= JsonConvert.DeserializeObject<List<T>>(jsonData)
?? new List<T>();
// Add any new
SomeObjectList.Add(new T()
{
Name = "..."
});
SomeObjectList.Add(new T()
{
Name = "..."
});
// edit
var first = SomeObjectList.FirstOrDefault();
first.Name = "...";
// Update json data string
jsonData = JsonConvert.SerializeObject(SomeObjectList);
System.IO.File.WriteAllText(filePath, jsonData);
Open the file read/write,
parse through until you get to the closing curly brace, then write
the remaining data, then write the close curly brace (not trivial)
Instead of messing around with JProperty, deserialize your json and append your desired data:
JObject obj = JObject.Parse(jsontext);
obj["new_prop"] = "value";//new property as per hirarchy ,same for replacing values
string newjson=obj.ToString();
it's much cleaner and easier to maintain.
I created an application on UWP whose data is parsed to JSON with JSON as below:
JSON
I'm having trouble parsing json on "jawaban" and an error message appears like below:
Code:
JsonArray jsonDataOption = groupObjectSoal["jawaban"].GetArray();
foreach (JsonValue groupValueOption in jsonDataSoal)
{
JsonObject groupObjectOption = groupValueSoal.GetObject();
string oid = groupObjectOption["oid"].GetString();
string option = groupObjectOption["q_option"].GetString();
string score = groupObjectOption["score"].GetString();
QuizOption pilihan = new QuizOption();
pilihan.OID = oid;
pilihan.Option = option;
pilihan.Score = score;
}
How to handle it?
Note:
For the full code, can be seen here
Property "list_soal" contains an array with two elements. The first element does not have property "jawaban", so your code fails on parsing first element
Use JSON.net
Newtonsoft
There are plenty examples on the site.
It will automatically fill your data model.
You can deserialize to object by calling.
YourObject m = JsonConvert.DeserializeObject<YourObject>(json);
where json is your json string and YourObject is your model
I'm trying to output JSON to a drop down list in a web form. I've managed to get this far:
WebClient client = new WebClient();
string getString = client.DownloadString("http://myfeed.com/app_feed.php");
JavaScriptSerializer serializer = new JavaScriptSerializer();
dynamic item = serializer.Deserialize<object>(getString);
string name = item["title"];
return name;
This brings back the feed ok but it runs into an error on the line:
string name = item["title"];
Bringing back this error:
Additional information: The given key was not present in the dictionary.
This is a sample of my feed:
{"apps":[{"title":"title1","description":"description1"},
{"title":"title2","description":"description2"},
{"title":"title3","description":"description3"}
So I thought that I was referencing the first title and I was planning to loop through them:
string name = item["title"];
But obviously not!
I have looked on Stackoverflow but I can't find an answer that I can apply to my own code.
title is inside another key apps and its an array so you should iterate it, I show you just select first one using index 0
string name = item["apps"][0]["title"];
you can access all by foreach
foreach (var ap in item["apps"])
{
Console.WriteLine(ap["title"]);
}
First, your JSON is invalid. Second: you need to loop over your items, as it is an array. If you want to access the first one, you could do: item["apps"][0]["title"]
Looping through all items:
var str = #"{""apps"":[{""title"":""title1"",""description"":""description1""},
{""title"":""title2"",""description"":""description2""},
{""title"":""title3"",""description"":""description3""}]}";
var serializer = new JavaScriptSerializer();
dynamic obj = serializer.Deserialize<object>(str);
foreach (var item in obj["apps"])
{
Console.WriteLine("item title: " + item["title"]);
}
Hi so am trying to parse this JSON line but i got some others that are like this in files thats why i want to automate this so i can remove the invalid lines to make the file a valid JSON for reading, The problem is that the JSON contains multiple JSON in 1 line
Example:
{"item":"value"}{"anotheritem":"value"}
Is there anyway to remove
{"anotheritem":"value"}
So it turns in to a valid JSON that is readable to start parsing the files
I tried doing using StreamReader cause there in a file i have multiple files that contain these invalid JSON
So i got it to be able to detect the Invalid JSON but for some reason i can't get it to read the JSON so i can use .remove to remove the invalid line
using (StreamReader r = new StreamReader(itemDir))
{
string json = r.ReadToEnd();
if (json.Contains("anotheritem"))
{
JObject NoGood = JObject.FromObject(json);
MessageBox.Show(NoGood.ToString());
}
}
The Error:
Object serialized to String. JObject instance expected.
Thank you all for your time and help.
If each object are side by side without space or any other character, you can convert your string to an json array.
string value = "{\"item\":\"value\"}{\"anotheritem\":\"value\"}";
string arrayValue = "[" + value.Replace("}{", "},{") + "]";
var array = JArray.Parse(arrayValue);
var goopArray = array.OfType<JObject>().Where(o => o.Property("anotheritem") == null);
Edit : see my second answer. More robust solution. More modern. And support dotnet core builtin json serializer.
Json.Net
Even better solution, Json.NET have a builtin feature for this exact scenario. See Read Multiple Fragments With JsonReader
The JsonTextReader have a property SupportMultipleContent that allow to read consecutive items when set to true
string value = "{\"item\":\"value\"}{\"anotheritem\":\"value\"}";
var reader = new JsonTextReader(new System.IO.StringReader(value));
reader.SupportMultipleContent = true;
var list = new List<JObject>();
while (reader.Read())
{
var item = JObject.Load(reader);
list.Add(item);
}
System.Text.Json
If you want to use System.Text.Json, it's also acheivable. They are no SupportMultipleContent property but Utf8JsonReader will do the job for you.
string value = "{\"item\":\"value\"}{\"anotheritem\":\"value\"}";
var bytes = Encoding.UTF8.GetBytes(value).AsSpan();
var list = new List<JsonDocument>();
while (bytes.Length != 0)
{
var reader = new Utf8JsonReader(bytes);
var item = JsonDocument.ParseValue(ref reader);
list.Add(item);
bytes = bytes.Slice((int) reader.BytesConsumed);
}
The JSON structure that is being investigated looks like:
string jsonText
= #"{ ""348975"":{""name"":""nam1"",""value"":1}"
+ #", ""876132"":{""name"":""nam2"",""value"":2}"
+ #", ... }";
One needs to select the value element for the object that has a given name. For the above JSON, suppose the given name is "nam2", the returned valued would have to be 2. One tried to use:
JObject jsonObject = JObject.Parse(jsonText);
string searchName = "nam2";
JToken myValue = jsonObject.SelectToken("[?(#.name=" + searchName + ")].value");
and similar JSON path strings, but with no success.
It is possible and simple to do with iteration over all the elements, but one needs to know if it can be done with SelectToken.
Please assist.
Thank you!
I wasn't able to get this to work using JSONPath, I tried the following which seems like it should work:
$.*[?(#.name == 'nam1')]
However it doesn't. You can use LINQ to JSON instead though if your only goal is to do it in one line:
JToken myValue = jsonObject.SelectTokens("$.*")
.SingleOrDefault (jt => jt["name"]
.Value<string>() == searchName);