parsing JSON with Json.Net to get the Key - c#

Searched my question and didnt find the answer, I have a JSON file like below:
{
"handle":"ABCD",
"Tracks":{
"Design":{
"rating":402
},
"Development":{
"rating":1584,
"reliability":"n/a"
},
"Specification":{
"rating":923,
"reliability":"0.13"
},
"Conceptualization":{
"rating":895
}
}
}
I am getting a dynamic object of json:
dynamic dynObj;
dynObj = JsonConvert.DeserializeObject(content);
how can I get the name of "Tracks" item? I dont know how many tag like "Design" is there nor I know the name of them...

In your (dynamic) scenario, don't use dynamic, it does not make sense, since you are looking for schema information about the document, which becomes unavailable through the dynamic model.
So, get a JObject by calling JObject.Parse on your JSON data.
Then, get the keys as such (taken from the JObject.Properties documentation):
foreach (var prop in myJObject.Properties())
{
//returns 'handle' and 'Tracks' for your root object
Console.WriteLine("{0} - {1}", prop.Name, prop.Value);
}
Or using the enumerator of the JObject:
foreach (var kvp in myJOBject)
{
Console.WriteLine("{0} - {1}", kvp.Key, kvp.Value);
}

Related

Extracting data from JSON structure in C#

JSON data:
{
"return": {
"output01": "Test request success!!",
"output02": "test request"
}
}
C# code:
JObject obj = JObject.Parse(jsonString);
JToken jToken = obj["return"];
foreach (JToken item in jToken)
{
string output1_param = item["output01"].ToString();
string output2_param = item["output02"].ToString();
}
Think of a repeat case.
System.InvalidOperationException: 'Cannot access child value on
Newtonsoft.Json.Linq.JProperty.'
What's wrong?
item is a JProperty, so it does not support indexer by object key (for example string one). You need either strip foreach:
JToken jToken = obj["return"];
string output1_param = jToken["output01"].ToString();
string output2_param = jToken["output02"].ToString();
Or work with Values of item, for example via First:
foreach (JToken item in jToken)
{
Console.WriteLine(item.First.ToString());
}
Also in this case casting to JProperty in foreach is also an option:
foreach (JProperty item in jToken)
{
Console.WriteLine($"{item.Name} - {item.Value}");
}
as you can see in This Link, indexer of JToken does not implemented and your code tries to using indexer of JToken.
When you call GetEnumerator of jToken, in this sample you will get just single element which is JProperty, so calling indexer of JProperty(by using string key) which implemented JToken will try using this indexer and throws exception.
what happens if you call using this way:
jToken["output01"].ToString();
in this pattern you are using indexer of JObject, which iterates over ChildrenTokens of JObject and give you values.
as Guru said you must read value using value field or use First element.

How to convert the following JSON array into IDictionary<string, object>?

Following is the serialized JSON array I want to convert to IDictionary
[
{
"8475": 25532
},
{
"243": 521
},
{
"3778": 15891
},
{
"3733": 15713
}
]
When I tried to use
JsonConvert.DeserializeObject<IDictionary<string, object>>((string)jarray);
I got an error saying:
Cannot cast 'jarray' (which has an actual type of 'Newtonsoft.Json.Linq.JArray') to 'string'
The JSON deserializer requires only a string.
If you already have the JArray, all you have to do is convert it to a dictionary I guess.
Roughly something like this:
IDictionary<string,object> dict = jarray.ToDictionary(k=>((JObject)k).Properties().First().Name, v=> v.Values().First().Value<object>());
Check this for complete code with an example
I think there might be a better way to convert it to a dictionary though. I'll keep looking.
the JsonConvert.DeserializeObject<T> Method takes a JSON string, in other words a serialized object.
You have a deserialized object, so you'll have to serialize it first, which is actually pointless, considering you have all the information you need right there in the JArray object. If you are aiming just to get the objects from the array as key value pairs, you can do something like this:
Dictionary<string, object> myDictionary = new Dictionary<string, object>();
foreach (JObject content in jarray.Children<JObject>())
{
foreach (JProperty prop in content.Properties())
{
myDictionary.Add(prop.Name, prop.Value);
}
}
To turn your JArray into a string, you'll need to assign the key & values of the dictionary for each element. Mario gave a very accurate approach. But there's a somewhat prettier approach as long as you know how to convert each item into your desired type. The below example is for Dictionary<string, string> but can be applied to any Value type.
//Dictionary<string, string>
var dict = jArray.First() //First() is only necessary if embedded in a json object
.Cast<JProperty>()
.ToDictionary(item => item.Name,
item => item.Value.ToString()); //can be modified for your desired type

Getting the name / key of a JToken with JSON.net

I have some JSON that looks like this
[
{
"MobileSiteContent": {
"Culture": "en_au",
"Key": [
"NameOfKey1"
]
}
},
{
"PageContent": {
"Culture": "en_au",
"Page": [
"about-us/"
]
}
}
]
I parse this as a JArray:
var array = JArray.Parse(json);
Then, I loop over the array:
foreach (var content in array)
{
}
content is a JToken
How can I retrieve the "name" or "key" of each item?
For example, "MobileSiteContent" or "PageContent"
JToken is the base class for JObject, JArray, JProperty, JValue, etc. You can use the Children<T>() method to get a filtered list of a JToken's children that are of a certain type, for example JObject. Each JObject has a collection of JProperty objects, which can be accessed via the Properties() method. For each JProperty, you can get its Name. (Of course you can also get the Value if desired, which is another JToken.)
Putting it all together we have:
JArray array = JArray.Parse(json);
foreach (JObject content in array.Children<JObject>())
{
foreach (JProperty prop in content.Properties())
{
Console.WriteLine(prop.Name);
}
}
Output:
MobileSiteContent
PageContent
JObject obj = JObject.Parse(json);
var attributes = obj["parent"]["child"]...["your desired element"];
foreach (JProperty attributeProperty in attributes)
{
var attribute = attributes[attributeProperty.Name];
var my_data = attribute["your desired element"];
}
The default iterator for the JObject is as a dictionary iterating over key/value pairs.
JObject obj = JObject.Parse(response);
foreach (var pair in obj) {
Console.WriteLine (pair.Key);
}
Using Linq we can write something like:
JArray array = JArray.Parse(json);
foreach (JObject content in array.Children<JObject>())
{
List<string> keys = content.Properties().Select(p => p.Name).ToList();
}
If the JToken key name is unknown, and you only need the key's Value regardless of name, simply use the JToken.Values() method.
The below sample assumes the JToken value is a primitive type - first value found is extracted.
Solution can be extended to support Array values.
JToken fooToken = sourceData.
int someNum = fooToken .Values<int?>().First() ?? 0;
int someString = fooToken .Values<string>().First();
The simplest way is to look at the path of each item in the JSON object.
For Each token As JToken In json
Dim key= token.Path.Split(".").Last
Next

using c# parse and iterate through json object to address each field

This is a very simple question but can't seem to find a direct answer. I read in a single JSON object. I then want to parse it and be able to directly address a token or a value and then format it for writing a file output, which I will use in another application. I am using C# and the Newtonsoft library.
My code:
JsonTextReader reader = new JsonTextReader(re);
while (reader.Read())
{
if (reader.Value != null)
Console.WriteLine("Value: {0}", "This is the value <Tags>: " + reader.Value);
}
How can I address each line? for example, desc and then Gets a reference to the game world. This must be so commoplace.
Thanks,
johnh
Use the JArray and JObject objects instead, like this:
var json = System.IO.File.ReadAllText("YourJSONFilePath");
var objects = JArray.Parse(json);
foreach(JObject root in objects)
{
foreach(KeyValuePair<String, JToken> tag in root)
{
var tagName = tag.Key;
Console.WriteLine("Value: {0}", "This is the value <Tags>: " + tagName);
}
}
Given a JToken token:
if (token.Type == JTokenType.Object)
{
foreach (var pair in token as JObject)
{
string name = pair.Key;
JToken child = pair.Value;
//do something with the JSON properties
}
}
else if (token.Type == JTokenType.Array)
{
foreach (var child in token.Children())
{
//do something with the JSON array items
}
}
else
{
//do something with a JSON value
}
Have a look at the properties of the reader as it's reading the string. Especially at the TokenType and Value properties. If you really need to read it sequentially that's the way to go. TokenType will be, in order, StartObject, PropertyName, String etc. depending on the node being read. Basically each time you see a PropertyName, the next one will be the property value.
Take note that you'd probably be better off using other techniques but it all depends.
I see that this thread is a bit old... However, #Karl Anderson, your answer was helpful. I just added a little bit to it which was way better than the 3 or 4 nested foreach loops that I had going on... see code below. Thank you for the help!
JArray jsonResponse = JArray.Parse(content);
Debug.WriteLine("\n\njsonResponse: \n" + jsonResponse);
foreach (JObject root in jsonResponse)
{
foreach (KeyValuePair<String, JToken> tag in root)
{
var tagName = tag.Key;
var variable = tag.Value;
Debug.WriteLine("Key: " + tagName + " Value: " + variable);
}
}

How to handle json object in codebehind

I have - var JsonObj = []; and I pushed some data into that and send it to codebehind using JQuery.ajax() method. I am able to receive in a method which has parameter like this
[WebMethod]
public static void SaveInfo(List<Object> userEnteredDetails)
{
}
And i loop thru the collection to get the data something like this,
foreach (object item in userEnteredDetails)
{
Dictionary<string, object> details = item as Dictionary<string, object>;
string name = details["customerName"] as string;
}
The problem here is, I am receiving more than 10 items in the collecton. So i cannot read another property in my above for loop. Something like this,
foreach (object item in userEnteredDetails)
{
Dictionary<string, object> details = item as Dictionary<string, object>;
string name = details["customerName"] as string;
string city= details["city"] as string;
}
Firsttime city wil throw an error, and next time customername. Because item variable will have one variable at a time. How to read all the more than 10 records efficiently since we dont have property, but can read only through an indexer (details["customerName"]).
Try this:
string name = String.Empty;
string city = String.Empty;
foreach (object item in userEnteredDetails)
{
Dictionary<string, object> details = item as Dictionary<string, object>;
if (details.ContainsKey("customerName"))
name = details["customerName"] as string;
if (details.ContainsKey("city"))
city= details["city"] as string;
}
You can enumerate the details Dictionary.
foreach(var kvp in details)
{
// do something with kvp.Key and kvp.Value
}
EDIT:
To get a one merged details dictionairy first, you can try this:
var details = list.Select(item => item as Dictionary<string, object>).SelectMany(d => d).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
One thing you could have a type with fields in them mapping to the list of objects. While making the ajax call stringify the json object. In your web method recieve it as string. Use Json Deserializer and deserialize it to the type you have created.
Theres a very flexible json framework (JSON.NET) which could help with this, definitley worth considering if your doing a lot of work with JSON http://json.codeplex.com/

Categories

Resources