Moving all properties from a nested JObject to the root - c#

I have the following json format that I need to change by removing the "root" element and then sending it for processing.
{
"deonItemDetails":[
{
"hsDesc":"",
"namePLU":"AGO LOCAL",
"taxRate":0.0,
"unitPrice":71.0,
"discount":0.0,
"hsCode":"",
"quantity":1.0,
"measureUnit":"Litres",
"vatClass":"A"
}
],
"root":{
"senderId":"a4031de9-d11f-4b52-8cca-e1c7422f3c37",
"invoiceCategory":"tax_invoice",
"traderSystemInvoiceNumber":"34058",
"relevantInvoiceNumber":"",
"pinOfBuyer":"P051400323I",
"invoiceType":"Original",
"exemptionNumber":"",
"totalInvoiceAmount":71.0,
"systemUser":"manager"
}
}
I need it to be like this:
{
"deonItemDetails":[
{
"hsDesc":"",
"namePLU":"AGO LOCAL",
"taxRate":0.0,
"unitPrice":71.0,
"discount":0.0,
"hsCode":"",
"quantity":1.0,
"measureUnit":"Litres",
"vatClass":"A"
}
],
"senderId":"a4031de9-d11f-4b52-8cca-e1c7422f3c37",
"invoiceCategory":"tax_invoice",
"traderSystemInvoiceNumber":"34058",
"relevantInvoiceNumber":"",
"pinOfBuyer":"P051400323I",
"invoiceType":"Original",
"exemptionNumber":"",
"totalInvoiceAmount":71.0,
"systemUser":"manager"
}
However, using the following code, all content of root is removed instead of just the tag and brackets belinging to that node.
JObject jo = JObject.Parse(jsonToSendDetails);
jo.Property("root").Remove();
var newjson = jo.ToString();
How do I get the json to look like the 2nd one?

Solution 1
#JonSkeet had explained the concept:
Get the properties in the root.
Add the properties from 1 to the JObject.
Remove the root property from the JObject.
The below code is the implementation:
using Newtonsoft.Json.Linq;
JObject jObj = JObject.Parse(json);
JObject rootObj = (JObject)jObj["root"];
foreach (JProperty prop in rootObj.Properties())
{
jObj.Add(prop.Name, prop.Value);
}
jObj.Remove("root");
Demo Solution 1 # .Net Fiddle
Solution 2
Besides, you may work with JObject.Merge() as well.
using Newtonsoft.Json.Linq;
JObject jObj = JObject.Parse(json);
jObj.Merge(jObj["root"]);
jObj.Remove("root");
Demo Solution 2 # .NET Fiddle

just for the record
var jsonParsed = JObject.Parse(json);
var fixedObj = (JObject)jsonParsed["root"];
//if, most probably, the order of properties doesn't matter
fixedObj["deonItemDetails"] = jsonParsed["deonItemDetails"];
json = fixedObj.ToString();
// or if the order of properties matters
fixedObj.AddFirst( new JProperty("deonItemDetails", jsonParsed["deonItemDetails"]));

Related

C# Unable to modify Json with Newtonsoft

I have a string type variable named final and it contains the following Json:
{
"Game": {
"Player_Decks": {
"1": {
"Card_List": "2_Yellow,1_Blue,Reverse_Green,5_Yellow,5_Red,7_Red,2_Blue",
"Card_Count": 7
},
"2": {
"Card_List": "5_Blue,9_Green,4_Yellow,6_Green,0_Red,2_Green,6_Yellow",
"Card_Count": 7
}
},
"Deck_NoCards": {}
}
}
My code looks like this: (taken from here: https://www.newtonsoft.com/json/help/html/ModifyJson.htm)
JObject rss = JObject.Parse(final);
JObject channel = (JObject)rss["Game.Player_Decks.1"];
channel.Property("Card_Count").AddAfterSelf(new JProperty("new", "New value"));
I want to add another value after Card_Count, but I have a feeling that my string isn't "compatible" or something. What can be done here to fix my problem?
Reposting comment as answer here:
You cannot access the nested object using a dotted path "Game.Player_Decks.1". Instead you need to individually address each property within each object.
JObjects are effectively an array of named properties, JObject implements IDictionary<string, JToken?> so as long as each child element is also a JObject then you can use the string index to reference the element in the next level.
JObject game = (JObject)rss["Game"];
JObject decks = (JObject)game["Player_Decks"];
JObject channel = (JObject)decks["1"];
channel.Property("Card_Count").AddAfterSelf(new JProperty("new", "New value"));
The following syntax should also work:
JObject channel = rss["Game"]["Player_Decks"]["1"] as JObject;
Also, have you considered using a Json Array instead of properties named 1, 2, etc. like so:
{
"Game": {
"Player_Decks": [
{
"Card_List": "2_Yellow,1_Blue,Reverse_Green,5_Yellow,5_Red,7_Red,2_Blue",
"Card_Count": 7
},
{
"Card_List": "5_Blue,9_Green,4_Yellow,6_Green,0_Red,2_Green,6_Yellow",
"Card_Count": 7
}
],
"Deck_NoCards": {}
}
}
and accessed as:
JObject rss = JObject.Parse(final);
JObject game = (JObject)rss["Game"];
JArray decks = (JArray)game["Player_Decks"];
JObject deck1 = (JObject)decks[0];

insert data into existing JSON Array in C#

I need to add some more data into existing JSON
eg:
{
"OrderId":"abc",
"products":["a","b","c","etc"]
}
how to add more into products
The approach would be similar to used in answer to your previous question, but you will need to convert element to JArray:
var x = #"{
'OrderId':'abc',
'products':['a','b','c','etc']
}";
var jObj = JObject.Parse(x);
((JArray)jObj["products"]).Add("new");
Try this:
var jObject = JObject.Parse(json);
var jArray = jObject["products"] as JArray;
jArray?.Add("new_product");

Replace a JSON value of a property in several JObjects

I have a JSON file I'm reading from text and parsing it into JObject using Newtonsoft.Json.Linq. The JSON file looks like this:
{
"EntityTypeDto":[
{
"EntityType":"Grade",
"Language":"ES"
},
{
"EntityType":"ApplicationType",
"Language":"ES"
},
{
"EntityType":"Borough",
"Language":"ES"
}
]
}
Using the Newtonsoft library, are there any methods I can leverage on JObject to replace the Language property of all the objects to another value? If not what would be another way to do this? This project is a console application in C#, VS 2012, thanks.
You don't need Linq here to achieve what you need , Linq is for consult data, not for modify it. So you can just, eg, a foreach to iterate and modify the elements of the array:
JObject json= JObject.Parse(jsonString);
JArray entityTypeDtos= (JArray)json["EntityTypeDto"];
foreach(var e in entityTypeDtos)
{
if(e["Language"] != null)
e["Language"]="EN";
}
I'm guessing by the Linq tag you would like a Linq approach try this
string json = #"{
'EntityTypeDto':[
{
'EntityType':'Grade',
'Language':'ES'
},
{
'EntityType':'ApplicationType',
'Language':'ES'
},
{
'EntityType':'Borough',
'Language':'ES'
}
]
}";
JObject myjobj = JObject.Parse(json);
JArray EntityType = (JArray)myjobj["EntityTypeDto"];
(from eobj in EntityType
where eobj["Language"]="ES"
select eobj).ForEach(x => x["Language"]="New Value");

Removing an element from a JSON response

I have a JSON string from which I want to be able to delete some data.
Below is the JSON response:
{
"ResponseType": "VirtualBill",
"Response": {
"BillHeader": {
"BillId": "7134",
"DocumentId": "MN003_0522060",
"ConversionValue": "1.0000",
"BillType": "Vndr-Actual",
"AccountDescription": "0522060MMMDDYY",
"AccountLastChangeDate": "06/07/2016"
}
},
"Error": null
}
From above JSON response I want to able remove the
"ResponseType": "VirtualBill", part such that it looks like this:
{
"Response": {
"BillHeader": {
"BillId": "7134",
"DocumentId": "MN003_0522060",
"ConversionValue": "1.0000",
"BillType": "Vndr-Actual",
"AccountDescription": "0522060MMMDDYY",
"AccountLastChangeDate": "06/07/2016"
}
},
"Error": null
}
Is there an easy way to do this in C#?
Using Json.Net, you can remove the unwanted property like this:
JObject jo = JObject.Parse(json);
jo.Property("ResponseType").Remove();
json = jo.ToString();
Fiddle: https://dotnetfiddle.net/BgMQAE
If the property you want to remove is nested inside another object, then you just need to navigate to that object using SelectToken and then Remove the unwanted property from there.
For example, let's say that you wanted to remove the ConversionValue property, which is nested inside BillHeader, which is itself nested inside Response. You can do it like this:
JObject jo = JObject.Parse(json);
JObject header = (JObject)jo.SelectToken("Response.BillHeader");
header.Property("ConversionValue").Remove();
json = jo.ToString();
Fiddle: https://dotnetfiddle.net/hTlbrt
Convert it to a JsonObject, remove the key, and convert it back to string.
Sample sample= new Sample();
var properties=sample.GetType().GetProperties().Where(x=>x.Name!="ResponseType");
var response = new Dictionary<string,object>() ;
foreach(var prop in properties)
{
var propname = prop.Name;
response[propname] = prop.GetValue(sample); ;
}
var response= Newtonsoft.Json.JsonConvert.SerializeObject(response);

How to list a newtonsoft Jtoken or JObjects children in a listBox

I have a json file that i read to string and then convert to a jobject. I get a JToken from this object by selecting one of its children.
I want to list this JTokens children in a Listbox. I think, to do this i need to convert th eJTOken to a ListItem - how can i do this? If there is a better alternative way then would be interested to hear it!
string filePath = #"C:\output.json";
JObject json = JObject.Parse(System.IO.File.ReadAllText(filePath));
JToken jsonFiles = json["Files"];
jsonFilesListItem = ....
JsonListBox.Items.Add(jsonFilesListItem);
Assuming that json["Files"] contains a simple array of strings, all you have to do is use a foreach loop, as shown in the example below:
string jsonString = #"
{
""Files"": [
""foo.xml"",
""bar.txt"",
""baz.jpg"",
""quux.wav""
]
}";
JObject json = JObject.Parse(jsonString);
JToken jsonFiles = json["Files"];
foreach (string fileName in jsonFiles)
{
JsonListBox.Items.Add(fileName);
}

Categories