I am developing an app using c# wpf in .net 3.5.
I use newtonsoft library to parse the json string.
I want to know how to remove a child node of json.
For example,
My json data =
{"employees":[
{"firstName":"John", "lastName":"Doe"},
{"firstName":"Anna", "lastName":"Smith"},
{"firstName":"Peter", "lastName":"Jones"}]}
The function
jobject.Remove("employees");
removes all the nodes sucessfully
I would like to know how to remove the first employee detail alone.
Once you parse your json into a JObject, the employees property will be a JArray. The JArray class has methods you're looking for, such as JArray.RemoveAt
The following code will do what you want
string json =
#"{
""employees"":[
{ ""firstName"":""John"", ""lastName"":""Doe""},
{ ""firstName"":""Anna"", ""lastName"":""Smith""},
{ ""firstName"":""Peter"", ""lastName"":""Jones""}
]
}";
dynamic obj = JObject.Parse(json);
(obj.employees as JArray).RemoveAt(0);
// obj now only has "Anna Smith" and "Peter Jones"
dynamic was introduced in .NET 4.0, so for 3.5 you'd use something like this instead
JObject obj = JObject.Parse(json);
(obj["employees"] as JArray).RemoveAt(0);
obj.SelectToken("Employees")[0].Parent.Remove();
Related
I have a JSON text:
{
"a":[
{
"a1":"string",
"a2":"string",
"a3":"string"
}
],
"b":"2021-12-29T14:20:21.948Z",
"c":{
"c1":[
{
"c11":"string",
"c12":"string",
"c13":"string",
"c14":true,
"c15":true,
"c16":"2021-12-29T14:20:21.948Z",
"c17":"string"
}
]
}
}
JsonNode class always has a unique path I want to use them to find a specific value (update/delete them).
So, I want to use System.Text.Json and .NET 6 to have the following methods:
public static JsonNode UpdateValue(string json /*JsonNode json*/, string path, object value)
{
// ?
}
public static JsonNode RemovePath(string json /*JsonNode json*/, string path)
{
// ?
}
Is it possible?
In short: Unfortunately you can't
Modification
JsonDocument is readonly by design. Before JsonNode has been introduced you had to
deserialize it as Dictionary<string, object>
perform the modification
serialize it back to json
Since JsonNode has been introduced in .NET 6 you can do the following
var node = JsonNode.Parse(json);
var rootObject = node as JsonObject;
var aArray = rootObject["a"] as JsonArray;
var firstA = aArray[0];
firstA["a3"] = "modified";
or in short
var node = JsonNode.Parse(json);
node["a"][0]["a3"] = "modified";
Locate element by Path
Even though the need has been expressed in 2019 it hasn't been address yet. But as layomia said
This feature is proposed for .NET 6, but not committed. To be clear, we acknowledge that this is an important feature for many users, however, work on features with higher priority may prevent this from coming in .NET 6.
Unfortunately this feature did not make it to the .NET 6.
There are 3rd party libraries which offers this capability for JsonDocument. One of the most mature one is called JsonDocumentPath. With its SelectElement method you can really easily retrieve the given field as JsonElement
var doc = JsonDocument.Parse(json);
JsonElement? a3 = doc.RootElement.SelectElement("$.a[0].a3");
Interoperability
Even though there is a way to convert JsonElement to JsonNode and in the other way around:
var a3Node = JsonSerializer.Deserialize<JsonNode>(a3.Value);
a3Node = "a";
it does not really help since the a3Node represents only the a3 field and according to my understanding you can't just merge two JsonNodes.
update json using Newtonsoft.Json
string json = File.ReadAllText("json");
dynamic jsonObj = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
jsonObj["a"][0]["test1"] = "new values";
string output = Newtonsoft.Json.JsonConvert.SerializeObject(jsonObj, Newtonsoft.Json.Formatting.Indented);
Have to write a generic method which will take json of any structure and add new properties to each element with data
Structure # 1, (Person)
Input Json data,
{'name':'sam', 'age': 12}
Expected output,
{'name':'sam', 'name_xyz': 'Rob', 'age': 12, 'age_xyz': 15}
Structure # 2, (Person with address)
Input json data,
{ 'name': 'sam', address : { 'city': 'fishers', 'zip': 23456 } }
Expected output,
{'name': 'sam', 'name_xyz': 'rob', address : { 'city': 'fishers', 'city_xyz': 'fishers', 'zip': 23456, 'zip_xyz': 678768} }
Structure # 3 (Person's)
Input json data,
[{'name': 'sam'}, {'name':'rex'}]
Expected Output,
[{'name': 'sam', 'name_xyz': 'felix'}, {'name':'rex', 'name_xyz' : 'bob'}]
I have something for defined model using NewtonSoft, but I need generic method to parse and evaluate any type of json data.
var jsonData = JsonConvert.SerializeObject(modelData);
var jArray = JArray.Parse(jsonData) as JArray;
dynamic persons = jArray;
foreach (dynamic person in persons)
{
var name = person.name;
var newname = Getnewname(name);
person.Add(new JProperty("name_xyz", newname));
var age = person.age;
var newage = GetnewAge(age);
person.Add(new JProperty("age_xyz", newage));
}
var result = persons.ToString();
Things to consider,
Look for each node, determine if it is array or object
Found object, create new object at same level with same property post fix '_xyz'
Found Array, loop through each object and same step 2
It will be nth level depth
I have encountered a similar situation and I solved it using a "nested dictionary" approach. While it is always a pleasure to work in the comfort zone of strongly typed entities, there are times when creating C# classes might get too cumbersome. This was my situation.
Treat the entire JSON like a dictionary where one or more keys might store another Dictionary. And this might continue several levels deep. The method Jobject.Parse worked for me. The JObject works like a key-value collection and you can recursively retrieve more JObject instances as you traverse deeper.
Newtonsoft reference - flat dictionary
https://www.newtonsoft.com/json/help/html/SerializingCollections.htm
This will NOT work very well with a nested structure like yours.
Newtonsoft code snippet - parsing as a JObject
string json="[{'name': 'sam', 'name_xyz': 'felix'}, {'name':'rex', 'name_xyz' : 'bob'}]"
JObject o = JObject.Parse(json);
https://www.newtonsoft.com/json/help/html/ParseJsonObject.htm
Newtonsoft reference - JObject
https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JObject.htm
More examples on using JObject as opposed to hard typing
https://www.newtonsoft.com/json/help/html/QueryingLINQtoJSON.htm
I am having trouble understanding when to use JContainer, JObject, and JToken. I understand from the "standards" that JObject is composed of JProperties and that JToken is the base abstract class for all of the JToken types, but I don't understand JContainer.
I am using C# and I just bought LinqPad Pro 5.
I have a JSON data source in a file, so I'm deserializing that file's contents successfully using this statement:
string json;
using (StreamReader reader = new StreamReader(#"myjsonfile.json"))
{
json = reader.ReadToEnd();
}
At that point, I take the JSON string object and deserialize it to a JObject (and this might be my mistake--perhaps I need to make jsonWork a JToken or JContainer?):
JObject jsonWork = (JObject)JsonConvert.DeserializeObject(json);
In my JSON data (the string represented by JSON), I have three objects--the top-level object look similar to this:
{
"Object1" : { ... },
"Object2" : { ... },
"Object3" : { ... }
}
Each object is composed of all sorts of tokens (arrays, strings, other objects, etc.), so it is dynamic JSON. (I used ellipses as placeholders rather than muddying up this question wit lots of JSON data.)
I want to process "Object1", "Object2", and "Object3" separately using LINQ, however. So, ideally, I would like something like this:
// these lines DO NOT work
var jsonObject1 = jsonWork.Children()["Object1"]
var jsonObject2 = jsonWork.Children()["Object2"]
var jsonObject3 = jsonWork.Children()["Object3"]
But the above lines fail.
I used var above because I have no idea what object type I should be using: JContainer, JObject, or JToken! Just so you know what I want to do, once the above jsonObject# variables are properly assigned, I would like to use LINQ to query the JSON they contain. Here is a very simple example:
var query = from p in jsonObject1
where p.Name == "Name1"
select p
Of course, my LINQ ultimately will filter for JSON arrays, objects, strings, etc., in the jsonObject variable. I think once I get going, I can use LinqPad to help me filter the JSON using LINQ.
I discovered that if I use:
// this line WORKS
var jsonObject1 = ((JObject)jsonWork).["Object1"];
Then I get an JObject type in jsonObject1. Is this the correct approach?
It is unclear to me when/why one would use JContainer when it seems that JToken and JObject objects work with LINQ quite well. What is the purpose of JContainer?
You don't really need to worry about JContainer in most cases. It is there to help organize and structure LINQ-to-JSON into well-factored code.
The JToken hierarchy looks like this:
JToken - abstract base class
JContainer - abstract base class of JTokens that can contain other JTokens
JArray - represents a JSON array (contains an ordered list of JTokens)
JObject - represents a JSON object (contains a collection of JProperties)
JProperty - represents a JSON property (a name/JToken pair inside a JObject)
JValue - represents a primitive JSON value (string, number, boolean, null)
So you see, a JObject is a JContainer, which is a JToken.
Here's the basic rule of thumb:
If you know you have an object (denoted by curly braces { and } in JSON), use JObject
If you know you have an array or list (denoted by square brackets [ and ]), use JArray
If you know you have a primitive value, use JValue
If you don't know what kind of token you have, or want to be able to handle any of the above in a general way, use JToken. You can then check its Type property to determine what kind of token it is and cast it appropriately.
JContainer is a base class for JSON elements that have child items. JObject, JArray, JProperty and JConstructor all inherit from it.
For example, the following code:
(JObject)JsonConvert.DeserializeObject("[1, 2, 3]")
Would throw an InvalidCastException, but if you cast it to a JContainer, it would be fine.
Regarding your original question, if you know you have a JSON object at the top level, you can just use:
var jsonWork = JObject.Parse(json);
var jsonObject1 = jsonWork["Object1"];
Most examples have simple json and I've googled "C# Newtonsoft parse JSON" more than once.
Here's a bit of a json file I was just asked to parse for a csv. The company name value is nested within many arrays / objects so it is semi-complicated in that regard.
{
"page": {
"page": 1,
"pageSize": 250
},
"dataRows": [
{
"columnValues": {
"companyName": [
{
"name": "My Awesome Company",
}
]
}
}
]
}
var jsonFilePath = #"C:\data.json";
var jsonStr = File.ReadAllText(jsonFilePath);
// JObject implementation for getting dataRows JArray - in this case I find it simpler and more readable to use a dynamic cast (below)
//JObject jsonObj = JsonConvert.DeserializeObject<JObject>(jsonStr);
//var dataRows = (JArray)jsonObj["dataRows"];
var dataRows = ((dynamic)JsonConvert.DeserializeObject(jsonStr)).dataRows;
var csvLines = new List<string>();
for (var i = 0; i < dataRows.Count; i++)
{
var name = dataRows[i]["columnValues"]["companyName"][0]["name"].ToString();
// dynamic casting implemntation to get name - in this case, using JObject indexing (above) seems easier
//var name2 = ((dynamic)((dynamic)((dynamic)dataRows[i]).columnValues).companyName[0]).name.ToString();
csvLines.Add(name);
}
File.WriteAllLines($#"C:\data_{DateTime.Now.Ticks}.csv", csvLines);
I'm using "Newtonsoft.Json.Linq.JObject" in my application.
I have a method that receives a JObject in the format:
{
"PersonnelIds": "[31,32,33,34]"
}
And I want to parse the content of PersonnelIds to a List of Integers.
What is the best way of doing that?
I can see that the values of the PersonnelIds is written as string "[31,32,33,34]" so to parse it with this syntax you can use the following code
JObject jObject = JObject.Parse(myjson);
JToken jToken = jObject.GetValue("PersonnelIds");
var array = JArray.Parse(jToken.Value<string>()).Select(x => (int)x).ToArray();
if your value is not string so your JSON is like {"PersonnelIds": [31,32,33,34]
} then you can parse it using the following code
JObject jObject = JObject.Parse(myjson);
JToken jToken = jObject.GetValue("PersonnelIds");
int[] array = jToken.Values<int>().ToArray();
Create a class to deserialize your json:
To create classes, you can copy the json in clipboard and use the
Edit / Paste special / Paste JSON as class
in visual studio (I use vs2013).
Then deserialize your string.
See my solution on this post
I'm new to C# and I am building a WPF app. Right now I trying to figure out how I can parse a JSON string like this:
{
"Name": "Apple",
"ExpiryDate": "2008-12-28T00:00:00","Price": 3.99,
"Sizes": ["Small","Medium","Large"]
}
into a JSON Object magically.
I did some search online and all the solutions requires writing an object class that has the same structure as the JSON string. The string above is just an example and the actually JSON response is much more complicated, so I don't want to write a huge class for it.
Is there a library that allows me to do something similar to these:
JsonObject jo = new JsonObject(JsonString);
string name = jo["Name"]; // And the name would have "Apple" as its value
I'd recommend you use Json.NET as your JSON library. The following code creates a dynamic object that you can work with. magic is actually an instance of JObject in your example, by the way.
dynamic magic = JsonConvert.DeserializeObject(jsonStr);
string name1 = magic.Name; // "Apple"
string name2 = magic["Name"]; // "Apple"