I have a rather large JSON file I am attempting to parse and set definitions for in C#. I am getting an error from the Newtonsoft JSON Deserializer.
Newtonsoft.Json.JsonSerializationException: 'Error converting value 151 to type 'QA_Test1.json.states'. Path 'MyFlow.states[1]', line 8378, position 15.'
- InnerException {"Could not cast or convert from System.Int64 to QA_Test1.json.states."} System.Exception {System.ArgumentException}
Because this element is an array [] and has a nested list, side by side with anonymous integers. I'm stuck here
"states": [
{ .. some more json data
},
12,
14,
9,
10
]
The first problem (1) I don't even need the integer data, I need the nested data but the Newtonsoft Deserializer is still trying to deserialize the integer data without a def.
The second problem (2) The "variables" element has anonymous elements also, I want to get the names example anonomousVarName1 and get the properties of that item. But I wont know what they are. So having a definition I am finding difficult.
"states": [
{ .. some more json data
},
12, // problem 1
14,
9,
10
],
"variables": {
"anonomousVarName1": {
"blah": ".VariableImpl",
"blah": 407
},
"blah": false,
"blah": null
},
"anonomousVarName2": {
{
"blah": ".VariableImpl",
"blah": 407
},
"blah": false,
"blah": null
}
}
My definition
public class state_connections
{
[JsonProperty("states")]
public List<states> states { get; set; }
[JsonProperty("variables")]
public Dictionary<string, variables> variables { get; set; } // added resolution for problem 2
}
Problem #1 remains a huge issue problem #2 is resolved by using
Dictionary<string, variables> variables {get; set;}
Accessing the Dictionary variables
connections_def file = JsonConvert.DeserializeObject<connections_def>(_data_file, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All, MaxDepth = 200, NullValueHandling = NullValueHandling.Ignore });
foreach(var variable in file.automatonFlow.variables)
{
Console.WriteLine();
Console.WriteLine($"Variable Key Name: {variable.Key}");
Console.WriteLine("--- properties ---");
Console.WriteLine($" @class: {variable.Value.@class}");
Console.WriteLine($" @id: {variable.Value.id}");
Console.WriteLine($" defaultValue: {variable.Value.defaultValue}");
Console.WriteLine($" id: {variable.Value.long_id}");
Console.WriteLine($" name: {variable.Value.name}");
Console.WriteLine($" notes: {variable.Value.notes}");
Console.WriteLine($" secure: {variable.Value.secure}");
Console.WriteLine($" stateId: {variable.Value.stateId}");
Console.WriteLine($" type: {variable.Value.type}");
}
CodePudding user response:
Thank you Rivo for your assistance as clearly this could not be done without implementing List object. Still open to suggestions but here is what I found as a work-around and this is by far, a hack for a horribly designed JSON.
foreach(var state in file.automatonFlow.states)
{
//check if object is actually the json I want and not the stupid integers
if (state.GetType() == typeof(Newtonsoft.Json.Linq.JObject))
{
Console.WriteLine("--- states ---");
//convert the object BACK into text
var jobject = (JsonConvert.SerializeObject(state));
//convert the data BACK into definition form
states states = JsonConvert.DeserializeObject<states>(jobject, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All, MaxDepth = 200, NullValueHandling = NullValueHandling.Ignore });
Console.WriteLine($" @id: {states.id}");
Console.WriteLine($" actionClass: {states.actionClass}");
Console.WriteLine($" name: {states.name}");
Console.WriteLine();
}
}
Console.ReadLine();
Definition
public class connections_def
{
[JsonProperty("states")]
public List<object> states { get; set; }
[JsonProperty("variables")]
public Dictionary<string, variables> variables { get; set; }
}
---Outputs----
--- states ---
@id: 1
actionClass: HostCommandAction
name: Check Service running
CodePudding user response:
In your case, using List<object>
is more appropriate.
So your class definition should be :
public class state_connections
{
[JsonProperty("states")]
public List<object> states { get; set; }
[JsonProperty("variables")]
public Dictionary<string,string> variables { get; set; }
}