I have a configuration Json file that contains a List of dictionaries.
{
"Hardware": [
{
"Name": "name1",
"Model": "model1"
},
{
"Name": "name2",
"Model": "model2"
}
]
}
I am importing this Json into a variable using Newtonsoft.
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.IO;
using System.Windows.Forms;
namespace WindowsFormsApp2
{
public partial class Form1 : Form
{
public JObject Parameters;
public Form1()
{
InitializeComponent();
using (StreamReader file = File.OpenText("../../configuration.json"))
using (JsonTextReader reader = new JsonTextReader(file))
{
Parameters = (JObject)JToken.ReadFrom(reader);
}
}
}
}
This seem to work well and I can do things like:
`Parameters["Hardware"][0]["Name"].ToString()` -> returns "name1"
Now, I have two string variables with a new name and a new model (this variables come from a loop that iterates over a DataGridView, but that's not relevant to the question)
string Name = "name3";
string Model = "model3";
Following this question Creating JSON on the fly with JObject I have created a JToken containing this two variables, but I'm not sure how can I add them to Parameters["Hardware"]
I create a new JObject containing this name and model:
dynamic Aux = new JObject();
Aux.Name = "name3";
Aux.Model = "model3";
But if I try to do:
Parameters["Hardware"].Add(Aux);
It complains that JToken does not contain a definition for Add
I'm not sure why Parameters["Hardware"]
is a JToken and not a JArray.
I tried doing something Hacky like:
Parameters["Hardware"] = (JArray)Parameters["Hardware"];
Parameters["Hardware"].Add(Aux);
But the compiler still complains about Parameters["Hardware"]
being a JToken and won;t let me compile.
This is quite a basic thing, so I'm sure I might be doing something wrong and an easy solution exists, I just cannot figure it out.
At the end I want to have Parameters["Hardware"] like
{
"Hardware": [
{
"Name": "name1",
"Model": "model1"
},
{
"Name": "name2",
"Model": "model2"
},
{
"Name": "name3",
"Model": "model3"
}
]
}
So I can export it back to a Json file.
So far I only needed to read the data from the Json or modify it, which works well, but now that I have to add elements is where I'm facing some trouble.
I am happy to change the way I read the file, maybe storing it as a JObject is not the best. So any suggestion on how to end up with a list of dictionaries with added elements is welcome.
CodePudding user response:
You are getting that error because the JObject
indexer Parameters["Hardware"]
is declared to return an object of type JToken
:
public JToken this[ string propertyName ] { get; set; }
And JToken
, which is the abstract base class for JArray
, JObject
, JValue
and so on, has no Add()
method. You need to downcast to JArray
, which does have an Add()
method, like so
((JArray)Parameters["Hardware"]).Add(Aux);
Since c# is (mostly) statically typed and the indexer is declared to return JToken
you can only use the methods of the abstract base class JToken
. You must downcast to JArray
to use JArray
methods.
For a discussion of the LINQ to JSON type hierarchy see JContainer, JObject, JToken and Linq confusion.
CodePudding user response:
try this..
using (StreamReader file = File.OpenText("../../configuration.json"))
using (JsonTextReader reader = new JsonTextReader(file))
{
var Parameters = (JObject)JToken.ReadFrom(reader);
dynamic Aux = new JObject();
Aux.Name = "name3";
Aux.Model = "model3";
Parameters["Hardware"].Last.AddAfterSelf(Aux);
}