I have a JSON file
{
"RandonName": [
{
"RandomKey1": "Data",
"RandomKey2": "Data",
"RandomKey3": "Data",
"RandomKey4": "Data",
"RandomKey5": "Data"
},
{
"RandomKey1": "Data",
"RandomKey2": "Data",
"RandomKey3": "Data",
"RandomKey4": "Data",
"RandomKey5": "Data"
}
]
}
My Deserializer
JsonTextReader JTR = new JsonTextReader(stringReader);
JsonSerializer JS = new JsonSerializer();
var dictionary = JS.Deserialize(JTR) as IEnumerable<KeyValuePair<string, JToken>>;
My Print, output is RandonName
foreach(KeyValuePair<string, JToken> pair in sourceRoot)
{
Console.WriteLine(pair.Key);
}
Can I get somehow all Key names inside the array?
JsonSerializer.Deserialize() is a static method. You don't need to create instance for JsonSerializer.
Meanwhile JToken is from Newtonsoft.Json. I think would be great not to mix up with System.Text.Json and Newtonsoft.Json.
And deserialize as Dictionary<string, List<Dictionary<string, string>>> type.
Dictionary<string, List<Dictionary<string, string>>> dictionary = JsonSerializer.Deserialize<Dictionary<string, List<Dictionary<string, string>>>>(JTR);
// Iterate for first item in RandonName dictionary
foreach (KeyValuePair<string, string> kvp in dictionary["RandonName"][0])
{
Console.WriteLine(kvp.Key);
Console.WriteLine(kvp.Value);
}
// Iterate for all items in RandonName dictionary
foreach (var items in dictionary["RandonName"])
{
foreach (KeyValuePair<string, string> kvp in items)
{
Console.WriteLine(kvp.Key);
Console.WriteLine(kvp.Value);
}
}
Sample .NET Fiddle
To get all Keys (from the first item):
dictionary["RandonName"][0].Keys
To get all keys from every item in the list:
using System.Linq;
dictionary["RandonName"].SelectMany(x => x.Keys).ToList();
string json = #"{
'RandonName': [
{
'RandomKey1': 'Data',
'RandomKey2': 'Data',
'RandomKey3': 'Data',
'RandomKey4': 'Data',
'RandomKey5': 'Data'
},
{
'RandomKey1': 'Data',
'RandomKey2': 'Data',
'RandomKey3': 'Data',
'RandomKey4': 'Data',
'RandomKey5': 'Data'
}
]
}
";
Console.WriteLine(
JObject.Parse(json)["RandonName"][0].Children<JProperty>().Select(x => x.Name));
Will print out:
RandomKey1
RandomKey2
RandomKey3
RandomKey4
RandomKey5
The key to the one-liner is to cast the children of the first JObject to JProperty.
If you need only just the property names from the first object then you can take advantage of Json.NET's Linq
var semiParsedJson = JObject.Parse(json);
var collection = (JArray)semiParsedJson["RandonName"];
var firstObject = (JObject)collection.First();
foreach (var property in firstObject.Properties())
{
Console.WriteLine(property.Name);
}
Related
I have a big problem with deserializing my JSON to an object. It should be deserialized to IList<KeyValuePair<string, object>> the problem is that the keys have white spaces.
"spec": {
"SOMETHING WITH SPACES" : "10"
etc.
...
}
public class SomeObject
{
...
public IList<KeyValuePair<string, object>> spec{ get; set; }
...
}
Deserializing code:
var sr = new ServiceStack.Text.JsonSerializer<SomeObject>();
var esResult = sr.DeserializeFromString(responseJson);
responseJson is a GET from ElasticSearch.
What I get to my field it is null.
If I have key without whitespaces it's deserializing normally and I'm getting my IList<KeyValuePair<string, object>>
You can't use IList or List here, because your source JSON has no [ ] in it, which is a requirement if you want to parse into such a collection. In other words, without [ ] you can't parse into a collection, at least not without going through lots of hoops.
Instead you need to use a Dictionary as was suggested already in comments.
Note: I used Newtonsoft JsonConvert because you didn't state what your parser is, but that should make little or no difference to my arguments.
Working code:
var json = "{ \"spec\": { \"SOMETHING WITH SPACES\" : \"10\" } }";
var someObj = JsonConvert.DeserializeObject<SomeObject>(json);
public class SomeObject
{
public Dictionary<string, object> spec{ get; set; }
}
After that, you can cast the spec property to an IEnumerable and loop through whatever was found:
foreach (var pair in someObj.spec as IEnumerable<KeyValuePair<string, object>>)
{
Console.WriteLine(pair.Key + " -> " + pair.Value);
}
Or even convert it to a List:
var list = someObj.spec.ToList();
foreach (var pair in list)
{
Console.WriteLine(pair.Key + " -> " + pair.Value);
}
.NET Fiddle: https://dotnetfiddle.net/15l2R3
If you don't mind using Newtonsoft.Json:
const string json = #"{""spec"": { ""SOMETHING WITH SPACES"" : ""10"", ""SOMETHING WITH MORE SPACES"" : ""20"" }}";
dynamic data = JsonConvert.DeserializeObject(json);
Dictionary<string, string> list = data["spec"].ToObject<Dictionary<string, string>>();
foreach (var item in list)
{
Console.WriteLine(item.Key + ", " + item.Value);
}
I guess your JSON serialiazer makes some trouble. I'd recommend to use Newtonsoft.Json (in NuGet)
I've tried following code, and it works fine:
var o1 = new SomeObject() { spec = new List<KeyValuePair<string, object>>() };
o1.spec.Add(new KeyValuePair<string, object>("test with spaces", 10));
var r1 = Newtonsoft.Json.JsonConvert.SerializeObject(o1);
Console.WriteLine(r1);
var o2 = Newtonsoft.Json.JsonConvert.DeserializeObject<SomeObject>(r1);
var r2 = Newtonsoft.Json.JsonConvert.SerializeObject(o2);
Console.WriteLine(r2);
The outcome is
{"spec":[{"Key":"test with spaces","Value":10}]}
{"spec":[{"Key":"test with spaces","Value":10}]}
No null values, all works fine.
EDIT: I actually see no reason, why spaces should be any problem at all. They are just part of the string.
I have the following JObject as return by https://gate.io/api2#trade API. How do I iterate through each key which is a separate coin also get its value.
I tried to parse it using Newtonsoft JObject Parse like this:
var coinData = JObject.Parse(#"{
""result"": ""true"",
""available"": {
""BTC"": ""0.83337671"",
""LTC"": ""94.364"",
""ETH"": ""0.07161"",
""ETC"": ""82.35029899""
},
""locked"": {
""BTC"": ""0.0002"",
""YAC"": ""10.01""
}
}")["available"];
foreach (JToken item in coinData)
{
item.Key
}
but then JToken doesn't give access to key values. I don't know how to further parse it.
JSON received from gateio api:
{
"result": "true",
"available": {
"BTC": "0.83337671",
"LTC": "94.364",
"ETH": "0.07161",
"ETC": "82.35029899"
},
"locked": {
"BTC": "0.0002",
"YAC": "10.01"
}
}
EDIT: Should I break it with ':' while iterating in loop? This is working if i break it and replace quotes.
foreach (JToken item in coinData)
{
var data = item.ToString().Replace("\"", String.Empty).Split(':');
}
var data has two parts, 1 => coin name, 2 => balance.
Is there any other legit way?
JToken is base class for all types of json tokens. In your case though you want only json properties, so you need to filter by more narrow type - JProperty. You can filter to include only property tokens like this:
foreach (var item in coinData.OfType<JProperty>()) {
string coinName = item.Name;
// to parse as decimal
decimal balance = item.Value.Value<decimal>();
// or as string
string balanceAsString = item.Value.Value<string>();
}
I would suggest being very explicit about expecting the result of "available" to be another object, by casting to JObject. You can then call Properties() to get its properties, each as a JProperty. Here's a complete example to demonstrate:
using System;
using Newtonsoft.Json.Linq;
class Program
{
public static void Main()
{
string json = #"{
'result': 'true',
'available': {
'BTC': '0.83337671',
'LTC': '94.364',
'ETH': '0.07161',
'ETC': '82.35029899'
},
'locked': {
'BTC': '0.0002',
'YAC': '10.01'
}
}".Replace('\'', '"');
JObject root = JObject.Parse(json);
JObject coins = (JObject) root["available"];
foreach (JProperty property in coins.Properties())
{
string name = property.Name;
string value = (string) property.Value;
Console.WriteLine($"Name: {name}; Value: {value}");
}
}
}
Say I have a Json as below:
{
"Records123": {
"-count": "1",
"-count2": "2",
"-count3": "4",
"Metadata": {
"value": 2,
"sum": 5
}
}
}
How do I get only the root name i.e 'Records123' in this case for Json (using Json.net or any method) , the way we have XDocument.Root.Name.LocalName in XML...
How to get the Root attributes i.e 'count' in this case like we have XDocument.Root.Attributes() in XML?
You could use JObject like this
var jsonObject = JObject.Parse(jsonString);
foreach (var tmp in jsonObject)
{
Console.WriteLine(tmp.Key);
}
For your sample JSON this should give you Records123 on the console. You have to add some logic here to get the first item only, which is a bit more tricky to JProperty handling.
Edit
For getting the other properties use
var jsonObject = JObject.Parse(jsonString);
foreach(JObject jsonProperty in jsonObject.Children<JProperty>().First())
{
foreach (var property in jsonProperty.Properties())
{
Console.WriteLine(property.Name);
}
}
I have the following json data being returned to me and I need to check if the user has the 'public_actions' permission granted or not.
{"data":[{"permission":"installed","status":"granted"},{"permission":"public_profile","status":"granted"},{"permission":"email","status":"granted"},{"permission":"publish_actions","status":"granted"}]}
Having not really done anything with json data before, I'm not sure the recommended approach to essentially arrive at a true or false (whether that particular permission has been granted or not).
Json.NET is a popular high-performance JSON framework for .NET.
This how I read json string using Newtonsoft.Json.dll:
var json = #"{
data: [
{
permission: 'installed',
status: 'granted'
},
{
permission: 'public_profile',
status: 'granted'
},
{
permission: 'email',
status: 'granted'
},
{
permission: 'publish_actions',
status: 'granted'
}
]
}";
JObject jObjects = JObject.Parse(json);
foreach (KeyValuePair<String, JToken> kvpParent in jObjects)
{
var sMainKey = kvpParent.Key;
var objects = JArray.Parse(kvpParent.Value.ToString());
foreach (JObject jObj in objects)
{
foreach (KeyValuePair<String, JToken> kvp in jObj)
{
var sKey = kvp.Key; //permission
var sValue = (String)kvp.Value; //installed
}
}
}
Each KeyValuePair gets 2 count that is for permission and status keys.
I'm quite new to JSON, and am currently learning about (de)serialization.
I'm retrieving a JSON string from a webpage and trying to deserialize it into an object. Problem is, the root json key is static, but the underlying keys are dynamic and I cannot anticipate them to deserialize. Here is a mini example of the string :
{
"daily": {
"1337990400000": 443447,
"1338076800000": 444693,
"1338163200000": 452282,
"1338249600000": 462189,
"1338336000000": 466626
}
}
For another JSON string in my application, I was using a JavascriptSerializer and anticipating the keys using class structure. What's the best way to go about deserializing this string into an object?
Seriously, no need to go down the dynamic route; use
var deser = new JavaScriptSerializer()
.Deserialize<Dictionary<string, Dictionary<string, int>>>(val);
var justDaily = deser["daily"];
to get a dictionary, and then you can e.g.
foreach (string key in justDaily.Keys)
Console.WriteLine(key + ": " + justDaily[key]);
to get the keys present and the corresponding values.
You can use dynamic in .NET 4 or later. For example with JSON.NET I can do:
dynamic obj = JsonConvert.Deserialize<dynamic>("{x: 'hello'}");
You can then do:
var str = obj.x;
However, unsure how it will handle numeric keys. You can of course just use JObject directly itself, for example:
var obj = JObject.Parse("{'123456': 'help'}");
var str = obj["123456"];
Whenever you have JSON with dynamic keys it can usually be deserialized into a Dictionary<string, SomeObject>. Since the inner JSON keys are dynamic (in this question) the JSON can be modelled as:
Dictionary<string, Dictionary<string, int>>
I would recommend using NewtonSoft.Json (JSON.Net) or System.Text.Json (if you're working in .NET-Core 3.0 and up).
Newtonsoft.Json
Use DeserializeObject<T> from JsonConvert:
var response = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, int>>>(json);
System.Text.Json
Use Deserialize<T> from JsonSerializer:
var response = JsonSerializer.Deserialize<Dictionary<string, Dictionary<string, int>>>(json);
This is not convenient to use, because in с# can not be defined a variable starts with a number. Add prefix to keys.
Or try this:
string json = "
{ daily:[
{ key: '1337990400000', val:443447 },
{ key: '1338076800000', val:444693 },
{ key: '1338163200000', val:452282 },
{ key: '1338249600000', val:462189 },
{ key: '1338336000000', val:466626 }]
}";
public class itemClass
{
public string key; // or int
public int val;
}
public class items
{
public itemClass[] daily;
}
items daily = (new JavascriptSerializer()).Deserialize<items>(json);
Then you can:
var itemValue = items.Where(x=>x.key=='1338163200000').Select(x=>x.val).FirstOrDefault();