How to count the length of value array in JSON - c#

I have a JSON below:
{
"value": [
{
"name": "504896c031d2fcb9",
"location": "North Europe",
"properties": {
"state": "UNKNOWN",
"name": "504896c031d2fcb9",
"siteInstanceName": "504896c031d2fcb93ec",
"healthCheckUrl": null,
"machineName": "lw0s",
"containers": null
}
},
{
"name": "35aafa",
"location": "North Europe",
"properties": {
"state": "UNKNOWN",
"name": "35aafae",
"siteInstanceName": "35aafaeff",
"healthCheckUrl": null,
"machineName": "lw1s",
"containers": null
}
}
],
"nextLink": null,
"id": null
}
I have converted JSON to a dynamic as mentioned below:
string kq = reader.ReadToEnd();
dynamic jss = JsonConvert.DeserializeObject(kq);
I want to know how to count how many values in C#? The above example has 2 values.
Thank you.

if you know the key you can do something like
dynamic jss = JsonConvert.DeserializeObject(kq);
jss["value"].Count

Cast as JArray and .Count.
Perhaps, if the value is not an array type, casted array will return as null.
You may add handling to check whether it is not null and get .Count.
dynamic jss = JsonConvert.DeserializeObject(kq);
JArray array = jss["value"] as JArray;
Console.WriteLine(array != null ? array.Count : 0);
Sample program (JsonConvert.DeserializeObject)
Recommendation:
Since you are deserializing JSON string to dynamic, with JsonConvert.DeserializeObject it will return the value of JObject type.
I would suggest using JObject.Parse rather than JsonConvert.DeserializeObject<T> (which is designed for converting to strongly-type object).
You may read this question: JObject.Parse vs JsonConvert.DeserializeObject for more info.
using Newtonsoft.Json.Linq;
JObject jss = JObject.Parse(json);
JArray array = jss["value"] as JArray;
Console.WriteLine(array != null ? array.Count : 0);
Sample program (JObject.Parse)

Related

How to access inner properties of a Json Object?

I am learning C# and I am trying to parse json/xml responses and check each and every key and value pair. For xml I am converting to json so I have only one function/script to work with both cases. My issue is that I am working with a wide range of json responses which are not similar and there may be arrays in some of the json response. I have tried accessing the "Count" of the json object as a way to check for arrays.
Note: The responses will vary. This example is for Products > Product > name, quantity and category. The next response will change and can be like Country > State > Cities and so on. I cannot rely on creating classes since all responses are going to be different. Plus I am working on automating it so it should be able to handle anything thrown at it.
Sample Json I am working with:
{
"products": {
"product": [
{
"name": "Dom quixote de La Mancha",
"quantity": "12",
"category": "Book"
},
{
"name": "Hamlet",
"quantity": "3",
"category": "Book"
},
{
"name": "War and Peace",
"quantity": "7",
"category": "Book"
},
{
"name": "Moby Dick",
"quantity": "14",
"category": "Book"
},
{
"name": "Forrest Gump",
"quantity": "16",
"category": "DVD"
}
]
}
The way I am accessing the count, name and value is as follows:
dynamic dyn = JsonConvert.DeserializeObject<dynamic>(jsonText);
foreach (JProperty property in dyn.Properties())
{
string propname = property.Name;
var propvalue = property.Value;
int count = property.Count;
}
Is there a way to access these without going through the foreach loop like int count = dyn.Count ? All I am getting from this is null instead of actual values.
For the above example my end result will be like:
This responses contains products> product> 5 x (name, quantity, category)
The QuickWatch for the object:
QuickWatch for dyn object
Try to deserialize your JSON into JObject like below:
var jObject = JsonConvert.DeserializeObject<JObject>(jsonText);

How to remove parent element from json in c#

How to covert the below json
{"data":{"id":12,"name":"jeremy","email":"jeremy#test.com"}}
to
{"id":12,"name":"jeremy","email":"jeremy#test.com"}
I want to remove the "data" element from json.
With json.net it's fairly straightforward
var input = "{\"data\":{\"id\":12,\"name\":\"jeremy\",\"email\":\"jeremy#test.com\"}}";
var result = JObject.Parse(input)["data"].ToString(Formatting.None);
Console.WriteLine(result);
Note : Formatting.None is only to preserve the formatting you had in your original example
Or Text.Json
var result = JsonDocument.Parse(input).RootElement.GetProperty("data").ToString();
Output
{"id":12,"name":"jeremy","email":"jeremy#test.com"}
Additional Resources
JObject.Parse Method (String)
Load a JObject from a string that contains JSON.
JObject.Item Property (String)
Gets or sets the JToken with the specified property name.
JToken.ToString Method (Formatting,JsonConverter[])
Returns the JSON for this token using the given formatting and
converters.
Formatting Enumeration
None 0 No special formatting is applied.
Text.Json
JsonDocument.Parse Method
Provides a mechanism for examining the structural content of a JSON
value without automatically instantiating data values.
JsonDocument.RootElement Property
Gets the root element of this JSON document
JsonElement.GetProperty Method
Gets a JsonElement representing the value of a required property
identified by propertyName.
I have a follow up question on a scenario where I don't want to remove the root element.
{
"keepMe": {
"removeMe": [
{
"id": "1",
"name": "Foo",
"email": "Foo#email.com"
},
{
"id": "2",
"name": "Bar",
"email": "Bar#email.com"
}
]
}
But I wanted it to look like
{
"keepMe": {
{
"id": "1",
"name": "Foo",
"email": "Foo#email.com"
},
{
"id": "2",
"name": "Bar",
"email": "Bar#email.com"
}
}
Using below would not work. Is there another way to do this?
var result = JObject.Parse(input)["keepMe"]["removeMe"].ToString(Formatting.None);
//{
// "id": "1",
// "name": "Foo",
// "email": "Foo#email.com"
//},
//{
// "id": "2",
// "name": "Bar",
// "email": "Bar#email.com"
//}
var result = JObject.Parse(input)["removeMe"].ToString(Formatting.None); //Null Reference
Found the answer using the SelectToken and Replace keyword
var jObj = JObject.Parse(input);
jObj.SelectToken("keepMe").Replace(jObj.SelectToken("keepMe.removeMe"));
string result = jObj.ToString();

'Accessed JObject values with invalid key value: 1. Object property name expected.'

I am trying to get JSON data from an api.
I have this json with me:
{
"elements": [
{
"id": 1,
"name": "Bob",
"address": "abc street",
"hobbies": {
"indoor": "Games, reading books",
"outdoor": ""
}
},
{
"id": 2,
"name": "Mark",
"address": "def street",
"hobbies": {
"indoor": "Games, reading books",
"outdoor": ""
}
}
]
}
I have this code with me:
using(var httpClient = new HttpClient()) {
HttpResponseMessage response = httpClient.GetAsync("api_url_here").Result;
var studentJsonString = response.Content.ReadAsStringAsync().Result;
var Jsresult = new JavaScriptSerializer().Deserialize<dynamic>(studentJsonString).ToString();
JObject jObject = JObject.Parse(Jsresult);
IEnumerable<dynamic> listDyn = jObject[0].Select(items => new StudentModel// gives error here as whole
{
id = items["id"].ToString(),
name = items["name"].ToString(),
address= items["address"].ToString()
});
}
But when I am calling the above method but it is giving me an error:
'Accessed JObject values with invalid key value: 1. Object property name expected.'
What am I missing?
Why are you deserializing twice? The result of
JavaScriptSerializer().Deserialize(customerJsonString)
is already an object. You don't need to parse it again with JObject.Parse(). You can just do
JObject jObject= JObject.Parse(customerJsonString)
Furthermore the result of JObject.Parse() is a dictionary and not an array. It has properties, which you can access by their names. For instance
jObject["elements"]
But of course, the compiler can't possibly predict, that jObject["elements"] will be an IEnumerable, so you will have to make sure of that.
jObject.Value<JArray>("elements").Select(item => ...)
This reads the property elements, of jObject as a JArray.

C# get value from deserialized json object

I'm currently Deserializing a json string using the Newtonsoft.Json nuget packet using the following code:
var data = (JObject)JsonConvert.DeserializeObject(json);
Now I'm receiving an object in the following format:
{{ "meta": { "rap": 2098, "count": 5 }, "data": [ { "name": "Gold Tetramino of Mastery", "rap": 735, "uaid": "16601901", "link": "https://www.roblox.com/Gold-Tetramino-of-Mastery-item?id=5786047", "img": "https://t4.rbxcdn.com/081337d7ea86e6a406512aaa83bbcdeb", "serial": "---", "count": 1 }, { "name": "Silver Tetramino of Accomplishment", "rap": 385, "uaid": "16601900", "link": "https://www.roblox.com/Silver-Tetramino-of-Accomplishment-item?id=5786026", "img": "https://t1.rbxcdn.com/60da69cd76f8dad979326f63f4a5b657", "serial": "---", "count": 1 }, { "name": "Subzero Ski Specs", "rap": 370, "uaid": "155175547", "link": "https://www.roblox.com/Subzero-Ski-Specs-item?id=19644587", "img": "https://t4.rbxcdn.com/8ead2b0418ef418c7650d34103d39b6d", "serial": "---", "count": 1 }, { "name": "Rusty Tetramino of Competence", "rap": 319, "uaid": "16601899", "link": "https://www.roblox.com/Rusty-Tetramino-of-Competence-item?id=5785985", "img": "https://t2.rbxcdn.com/968ad11ee2f4ee0861ae511c419148c8", "serial": "---", "count": 1 }, { "name": "Bluesteel Egg of Genius", "rap": 289, "uaid": "16601902", "link": "https://www.roblox.com/Bluesteel-Egg-of-Genius-item?id=1533893", "img": "https://t7.rbxcdn.com/48bf59fe531dd1ff155e455367e52e73", "serial": "---", "count": 1 } ]}}
Now I'm trying to get the following value from it:
"rap": 2098,
I just need 2098 and I've been trying the following code:
string rap = data["rap"].Value<string>();
But sadly this wouldn't work. Does anyone have a idea how to get the value?
Try:
var result = data["meta"]["rap"].Value<int>();
or
var result = data.SelectToken("meta.rap").ToString();
or if you don't want to want to pass the whole path in, you could just search for the property like this:
var result = data.Descendants()
.OfType<JProperty>()
.FirstOrDefault(x => x.Name == "rap")
?.Value;
Instead of declaring as type var and letting the compiler sort it, declare as a dynamic and using the Parse method.
dynamic data = JArray.Parse(json);
Then try
data.meta.rap
To get the internal rap object.
I edited from using the deserializeobject method as i incorrectly thought that had the dynamic return type. See here on json.net documentation for more details: http://www.newtonsoft.com/json/help/html/QueryJsonDynamic.htm
I just came to add Yet another way to get 2098:
After having got your object in the way you actually did:
var data = (JObject)JsonConvert.DeserializeObject(json);
The first you have to note is that the value you want to get is itself a value of the property "meta":
so, first you have to extract the contents of "meta" by simply calling
data["meta"]
and just then you are able to ask for the Value<string> of "rap":
String rap = data["meta"].Value<string>("rap");
which acctually gives you the value you were looking for:
Console.WriteLine(rap); // 2098
var jobject = (JObject)JsonConvert.DeserializeObject(json);
var jvalue = (JValue)jobject["meta"]["rap"];
Console.WriteLine(jvalue.Value); // 2098
The value is actually an int type. Try:
int rap = data["rap"].Value<int>();
string rap = JsonConvert.DeserializeObject<dynamic>(json).meta.rap;
Console.WriteLine(rap); // 2098
If you're not into dynamic (or aren't using .NET 4+), I like how this other answer relies solely on Json.NET's API.
Try to use as following
var test = JsonConvert.DeserializeObject<dynamic>(param);
var testDTO = new TPRDTO();
testDTO.TPR_ID = test.TPR_ID.Value;
Note: For using of JsonConvert class you have to install Newton-Soft from your package-manager
the problem is that you are casting the deserialized json into a JObject. if you want to have the JObject then simple do this:
JObject.Parse(json);
then you have the JObject and you can access a specific path (for extracting value see this )
you have also another option which is to deserialize your json into a class that you have in your code like this:
var instanceOFTheClass = JsonConvert.DeserializeObject<YourClassName>(json);
with the above code you can access any property and values you want.
Use the enumerator to get at the value:
var data = (JObject)JsonConvert.DeserializeObject(json);
var enumerator = data.GetEnumerator();
enumerator.MoveNext();
var dataValue = enumerator.Current.Value.ToString();
Just use dynamic representation of object:
dynamic obj = JsonConvert.DeserializeObject(json)
var value = obj.meta.rap;
JObject easily convertable to dynamic type itself. You can either get string or int from this value:
var ivalue = (int)obj.meta.rap;
var svalue = (string)obj.meta.rap;

JSON.NET reader problem

i got some problem when i generate .json file from spring .json ,and i got this format
{ "models": [
{
"id":1,
"modelName":"dfdsf",
"created":{
"userFullname":"demo",
"time":"150301",
"date":"20110208",
"userId":"123"
},
"remark":"dsfdf",
"updated":"~unique-id~1"
},
{
"id":2,
"modelName":"test",
"created":{
"userFullname":"test",
"time":"150301",
"date":"20110210",
"userId":"124"
},
"remark":"test",
"updated":{
"userFullname":"test",
"time":"150301",
"date":"20110209",
"userId":"test"
}
}
]}
first time i used JObject Parse for convert
JObject job = JObject.Parse(fullJson);
and the other hand i used jtoken to focus "models"
JToken jDetail = job["models"];
but the problem is {[{ xxx }]} it look like jarray i don't have any idea to convert it
i ever use JArray, JsonTextReader but it doesn't work.
could suggestion some? because if i pass this ll i set some value to object.
thank you for every idea.
string fullJson = File.ReadAllText("TextFile1.txt"); // for brevity
var job = JObject.Parse(fullJson);
var models = job.Value<JArray>("models");
Console.WriteLine(models[0]);
result:
{
"id": 1,
"modelName": "dfdsf",
"created": {
"userFullname": "demo",
"time": "150301",
"date": "20110208",
"userId": "123"
},
"remark": "dsfdf",
"updated": "~unique-id~1"
}

Categories