JSON.Net - Error when I get value from a JToken that could be either a JValue or JArray
-
I'm trying to select all users with a roleId of 4. How can I do that? Here's my JSON string:
{
"?xml" : {
"@version" : "1.0",
"@encoding" : "UTF-8"
},
"DataFeed" : {
"@FeedName" : "AdminData",
"People" : [{
"id" : "63",
"active" : "1",
"firstName" : "Joe",
"lastName" : "Schmoe",
"roleIds" : {
"int" : "4"
}
} , {
"id" : "65",
"active" : "1",
"firstName" : "Steve",
"lastName" : "Jobs",
"roleIds" : {
"int" : ["4", "16", "25", "20", "21", "22", "17", "23", "18"]
}
} , {
"id" : "66",
"active" : "1",
"firstName" : "Bill",
"lastName" : "Gates",
"roleIds" : {
"int" : ["3", "16", "25", "20"]
}
}
]
}
}Here's the query that I'm using:
JObject jsonFeed = JObject.Parse(jsonText);
from people in jsonFeed.SelectTokens("DataFeed.People").SelectMany(i => i.ObjectsOrSelf()) where (int)people\["active"\] == 1 && (int)people\["roleIds.int"\] == 4 // <-- this causes the error select new PeopleClass { Id = (int)people\["id"\], ResAnFName = (string)people\["firstName"\], ResAnLName = (string)people\["lastName"\] }
I'm getting the following error on
(int)people["roleIds.int"] == 4
:ArgumentNullException: Value cannot be null. Parameter name: value
In the end, my results should be:Joe Schmoe
&Steve Jobs
, only. What am I doing wrong? -
I'm trying to select all users with a roleId of 4. How can I do that? Here's my JSON string:
{
"?xml" : {
"@version" : "1.0",
"@encoding" : "UTF-8"
},
"DataFeed" : {
"@FeedName" : "AdminData",
"People" : [{
"id" : "63",
"active" : "1",
"firstName" : "Joe",
"lastName" : "Schmoe",
"roleIds" : {
"int" : "4"
}
} , {
"id" : "65",
"active" : "1",
"firstName" : "Steve",
"lastName" : "Jobs",
"roleIds" : {
"int" : ["4", "16", "25", "20", "21", "22", "17", "23", "18"]
}
} , {
"id" : "66",
"active" : "1",
"firstName" : "Bill",
"lastName" : "Gates",
"roleIds" : {
"int" : ["3", "16", "25", "20"]
}
}
]
}
}Here's the query that I'm using:
JObject jsonFeed = JObject.Parse(jsonText);
from people in jsonFeed.SelectTokens("DataFeed.People").SelectMany(i => i.ObjectsOrSelf()) where (int)people\["active"\] == 1 && (int)people\["roleIds.int"\] == 4 // <-- this causes the error select new PeopleClass { Id = (int)people\["id"\], ResAnFName = (string)people\["firstName"\], ResAnLName = (string)people\["lastName"\] }
I'm getting the following error on
(int)people["roleIds.int"] == 4
:ArgumentNullException: Value cannot be null. Parameter name: value
In the end, my results should be:Joe Schmoe
&Steve Jobs
, only. What am I doing wrong?As you said, the value can be an actual integer or an array, when it's an array it attempts to cast the array as an integer and it returns null value, which causes the error. What needs to happen here, you need to check first if it's an array and then search in the array
var roleFour = (from people in json.SelectTokens("DataFeed.People")
.SelectMany(i => i)
let ids = people["roleIds.int"]
where (int) people["active"] == 1 &&
(ids.Type == JTokenType.Array) ?
((int[]) ids.ToObject(typeof(int[]))).Any(k => k == 4) :
(int) ids == 4
select new {
Id = (int) people["id"],
ResAnFName = (string) people["firstName"],
ResAnLName = (string) people["lastName"]
}); -
I'm trying to select all users with a roleId of 4. How can I do that? Here's my JSON string:
{
"?xml" : {
"@version" : "1.0",
"@encoding" : "UTF-8"
},
"DataFeed" : {
"@FeedName" : "AdminData",
"People" : [{
"id" : "63",
"active" : "1",
"firstName" : "Joe",
"lastName" : "Schmoe",
"roleIds" : {
"int" : "4"
}
} , {
"id" : "65",
"active" : "1",
"firstName" : "Steve",
"lastName" : "Jobs",
"roleIds" : {
"int" : ["4", "16", "25", "20", "21", "22", "17", "23", "18"]
}
} , {
"id" : "66",
"active" : "1",
"firstName" : "Bill",
"lastName" : "Gates",
"roleIds" : {
"int" : ["3", "16", "25", "20"]
}
}
]
}
}Here's the query that I'm using:
JObject jsonFeed = JObject.Parse(jsonText);
from people in jsonFeed.SelectTokens("DataFeed.People").SelectMany(i => i.ObjectsOrSelf()) where (int)people\["active"\] == 1 && (int)people\["roleIds.int"\] == 4 // <-- this causes the error select new PeopleClass { Id = (int)people\["id"\], ResAnFName = (string)people\["firstName"\], ResAnLName = (string)people\["lastName"\] }
I'm getting the following error on
(int)people["roleIds.int"] == 4
:ArgumentNullException: Value cannot be null. Parameter name: value
In the end, my results should be:Joe Schmoe
&Steve Jobs
, only. What am I doing wrong?Can you change the Json source to force the "int" property to an array, so that your first value would be '["1"]'? That would simplify things considerably, especially since your cast is wrong for 2 of the supplied data elements (id 65 and 66 should be (int[])people["roleIds.int"].Contains(4) not (int)people["roleIds.int"] == 4).
"There are three kinds of lies: lies, damned lies and statistics." - Benjamin Disraeli
-
Can you change the Json source to force the "int" property to an array, so that your first value would be '["1"]'? That would simplify things considerably, especially since your cast is wrong for 2 of the supplied data elements (id 65 and 66 should be (int[])people["roleIds.int"].Contains(4) not (int)people["roleIds.int"] == 4).
"There are three kinds of lies: lies, damned lies and statistics." - Benjamin Disraeli
Sorry. I don't have any control over that. Yes, it makes more sense if it was always an array, but that's what I get from the web service feed.
-
As you said, the value can be an actual integer or an array, when it's an array it attempts to cast the array as an integer and it returns null value, which causes the error. What needs to happen here, you need to check first if it's an array and then search in the array
var roleFour = (from people in json.SelectTokens("DataFeed.People")
.SelectMany(i => i)
let ids = people["roleIds.int"]
where (int) people["active"] == 1 &&
(ids.Type == JTokenType.Array) ?
((int[]) ids.ToObject(typeof(int[]))).Any(k => k == 4) :
(int) ids == 4
select new {
Id = (int) people["id"],
ResAnFName = (string) people["firstName"],
ResAnLName = (string) people["lastName"]
});I'm getting the following error:
NullReferenceException: Object reference not set to an instance of an object.