Doing a simple JObject.parse(inJson) from Newtonsoft.json gives me the error Unable to cast object of type ‘Newtonsoft.Json.Linq.JValue’ to type 'Newtonsoft.Json.Linq.JObject.
I have checked the Json and it is a valid Json.
inJson:-
{
“img” : {
“exists” : “true”,
“motiv_id” : “G_NSA0_XX_01188”,
“relationship” : “exakt”,
“file_name” : “G_NSA0_XX_01188I.jpg”,
“file_full_path” : “F:\DATA\source\manufacturer\siemens\430_idb_asset\010__variant\G_NSA0_XX_01188I.jpg”,
“binary” : “”,
“size” : [300, 300]
}
}
I figured out that it is the node “size” : [300, 300] in the above Json causing the problem. If I remove it, it works fine. Can anyone help me with this. Thanks.
Hi @Shubham_Mawar
The error occurs because size is an array, not an object. To fix it, parse the JSON as JObject and access size as JArray:
Dim jsonObject As JObject = JObject.Parse(inJson)
Dim sizeArray As JArray = jsonObject("img")("size")
Dim width As Integer = sizeArray(0)
Dim height As Integer = sizeArray(1)
Avoid casting JArray to JObject.
If you found helpful, feel free to tick as a solution.
Happy Automation
Hi @prashant1603765, thanks for the prompt response. The problem is that the JSON comes to me at runtime and I have no way to know if there will be an array within the object or not. Is there a more generic way to tackle this? In my case the JSON can be a nested object with arrays within it. Thanks.
Parse the JSON with JObject.Parse(inJson)
and loop through properties. Check if the value is an object, array, or primitive. If it’s an object, process it; if it’s an array, loop through items; if it’s primitive, print it. This handles nested structures dynamically.
Hi get the exception while parsing itself at this line:-
JObject result = JObject.Parse(inJSON);
I cannot do anything after this.
You can run a test by executing the above piece of code and using the below JSON:-
{
"img" : {
"exists" : "true",
"motiv_id" : "G_NSA0_XX_01188",
"relationship" : "exakt",
"file_name" : "G_NSA0_XX_01188I.jpg",
"file_full_path" : "F:\\DATA\\source\\manufacturer\\siemens\\430_idb_asset\\010__variant\\G_NSA0_XX_01188I.jpg",
"binary" : "",
"size" : [300, 300]
}
}```
Works fine on my end:
Used the json from your last post (btw - added code tags there, otherwise the quotes get mangled on copying).
Studio 24.10.9, Newtonsoft.Json 13.0.0, C# project
Hi, you are right the problem is not at this particular line:-
JObject result = JObject.Parse(ssJSONin);
But I believe is somewhere when I am trying to handle the type JTokenType.Array. Below is my full code. This code is trying to run trough the full JSON and if any string value is more than 50 chars it does a substring and restrict it to 50 chars:-
public void MssParseDocument(string ssJSONin, out string ssJSONout) {
ssJSONout = "";
JObject result = JObject.Parse(ssJSONin);
foreach (JProperty property in result.Properties()) {
processJProperty(property);
}
ssJSONout = JsonConvert.SerializeObject(result, Formatting.None);
} // MssParseDocument
private void processJProperty(JProperty property) {
if (property.Value == null)
{
return;
}
if (property.Value.Type == JTokenType.String)
{
if (property.Value.ToString().Length > 50)
{
property.Value = property.Value.ToString().Substring(0, 50);
}
}
else if (property.Value.Type == JTokenType.Object)
{
foreach (JToken innerProperty in property.Children())
{
//processJProperty(innerProperty);
JObject obj = (JObject)innerProperty;
foreach (JProperty p in obj.Properties())
{
processJProperty(p);
}
}
}
else if (property.Value.Type == JTokenType.Array)
{
JArray array = (JArray) property.Value;
foreach (JToken innerProperty in array.Children()) {
if (innerProperty.Type == JTokenType.String) {
innerProperty.ToString();
JValue value = (JValue) innerProperty;
if (value.Value.ToString().Length > 50)
{
value.Value = value.Value.ToString().Substring(0, 50);
}
} else {
JObject obj = (JObject)innerProperty;
foreach (JProperty p in obj.Properties())
{
processJProperty(p);
}
}
}
}
}
I found the problem and fixed it. The problem was that I had assumed if inside an array if the value is not a string then it is an object:-
else if (property.Value.Type == JTokenType.Array)
{
JArray array = (JArray) property.Value;
foreach (JToken innerProperty in array.Children()) {
if (innerProperty.Type == JTokenType.String) {
innerProperty.ToString();
JValue value = (JValue) innerProperty;
if (value.Value.ToString().Length > 50)
{
value.Value = value.Value.ToString().Substring(0, 50);
}
} else {
JObject obj = (JObject)innerProperty;
foreach (JProperty p in obj.Properties())
{
processJProperty(p);
}
}
}
I changed it, and applied a check if type Object and not do anything if it is not an object:-
else if (property.Value.Type == JTokenType.Array)
{
JArray array = (JArray) property.Value;
foreach (JToken innerProperty in array.Children()) {
if (innerProperty.Type == JTokenType.String) {
innerProperty.ToString();
JValue value = (JValue) innerProperty;
if (value.Value.ToString().Length > 50)
{
value.Value = value.Value.ToString().Substring(0, 50);
}
} else {
if (innerProperty.Type == JTokenType.Object)
{
JObject obj = (JObject)innerProperty;
foreach (JProperty p in obj.Properties())
{
processJProperty(p);
}
}
else
{
}
}
}
}
Thank you guys for your support.
1 Like
Awesome!
That would be useful to know earlier 
Try this:
private string RestrictStringTokensToLength(string inJson, int maxLength)
{
JObject obj = JObject.Parse(inJson);
IEnumerable<JValue> stringTokens = obj.Descendants()
.OfType<JValue>()
.Where(v => v.Type == JTokenType.String);
foreach (JValue token in stringTokens)
{
string tokenValue = token.Value.ToString();
if (tokenValue.Length > maxLength)
{
token.Value = tokenValue.Substring(0, maxLength);
}
}
return JsonConvert.SerializeObject(obj, Formatting.None);
}
That’s a great solution. Thanks. 