I have a JSON data ( http://country.io/names.json ) like :
{"BD": "Bangladesh", "BE": "Belgium", "BF": "Burkina Faso", "BG": "Bulgaria", "BA": "Bosnia and Herzegovina", "BB": "Barbados" }
I want to list that json like CountryCode-CountryName (BD-Bangladesh) . How do I do that on windows form app. ?
You could deserialise the JSON into a Dictionary instead of a single object. This gives you access to all the codes and names, like so:
var json = #"{""BD"": ""Bangladesh"", ""BE"": ""Belgium"", ""BF"": ""Burkina Faso"", ""BG"": ""Bulgaria"", ""BA"": ""Bosnia and Herzegovina"", ""BB"": ""Barbados"" }";
var dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
foreach (var item in dict)
{
var countryCode = item.Key;
var countryName = item.Value;
// do whatever you want to do with those two values here
Console.WriteLine("CountryCode: {0} CountryName: {1}", countryCode, countryName);
}
In that code it simply writes it to the screen, but obviously once you have that loop in place you can do whatever you like with the country code and name.
Related
Is it possible to take a JSON object in C# that I read from from another source and convert the contents to files. The problem is I don't know the structure of the incoming objects.
So far I've got this:
var response = await client.GetAsync("https://blahblah/creds" +
"?ApiKey=" + textBox_password.Text +
"&deviceId=" + deviceId +
"&modelNum=" + modelNum);
var res = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var resJson = JsonConvert.DeserializeObject(res);
this.textBox_Stream.AppendText("responseBody = " + resJson + "\r\n");
Which gives me:
responseBody = {
"statusCode": 200,
"body": {
"modelNum": "42",
"creds": "[{\"deviceid.txt\":\"4DA23E\",\"pac.txt\":\"580795498743\"}]",
"deviceId": "4DA23E"
}
}
What I want to do is create a folder called 4DA23E and place one file inside it for each entry in the creds object.
device.txt will contain 4DA23E
pac.tct will contain 580795498743
etc. I can't figure out a dynamic way to extract the stuff I need. Goes without saying, I am not a C# programmer! So, please be kind.
Don't use JsonConvert.DeserializeObject. That's best when you know the schema of the JSON object and you've made a corresponding C# model.
First, parse the outer response JSON
var res = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
JObject resJson = JObject.Parse(res);
Now pull out the value of the "creds" property and re-parse it.
var credsJsonRaw = resJson["body"]["creds"].Value<string>();
JArray credsJson = JArray.Parse(credsJsonRaw);
Now you can loop through each object in the array, and each property in each object.
foreach (JObject obj in credsJson)
{
foreach (JProperty prop in obj.Properties)
{
Console.WriteLine($"Name = {prop.Name}");
Console.WriteLine($"Value = {prop.Value.Value<string>()}");
}
}
For your example, this prints
Name = deviceid.txt
Value = 4DA23E
Name = pac.txt
Value = 580795498743
One way to deserialise the following json is in two stages. This is because 'creds' is a string.
{
"statusCode": 200,
"body": {
"modelNum": "42",
"creds": "[{\"deviceid.txt\":\"4DA23E\",\"pac.txt\":\"580795498743\"}]",
"deviceId": "4DA23E"
}
}
Here's an example of how to do it. If you're not .NET6 change 'record' to 'class' and if you don't use nullable reference types (on by default in .NET6) remove the appropriate question marks in property definitions.
using System.Text.Json;
using System.Text.Json.Serialization;
var json = File.ReadAllText("data.json");
var o = JsonSerializer.Deserialize<Outer>(json);
if(o?.Body?.Creds == null)
{
throw new Exception("Bad data");
}
var credList = JsonSerializer.Deserialize<List<Dictionary<string, string>>>(o.Body.Creds);
if(credList == null)
{
throw new Exception("Bad data");
}
foreach( var e in credList)
foreach( var kvp in e)
Console.WriteLine($"{kvp.Key} : {kvp.Value}");
record Outer {
[JsonPropertyName("staticCode")]
public int? StaticCode {get; set;}
[JsonPropertyName("body")]
public Body? Body {get; set;}
}
record Body {
[JsonPropertyName("creds")]
public string? Creds {get; set;}
}
This prints
deviceid.txt : 4DA23E
pac.txt : 580795498743
I have a very simple use case, I Decode a json response received from an API as following
dynamic data = Json.Decode(APIContents);
This decodes the JSON for me and put it in data object. The only thing I know about this JSON is that this is an array of objects and array is called result. So if I want to get the first item I can simply do the following to get the first item
data.result[0]
Similarly if I want the ID of first item, I know there is a field in json called id so I can get the ID as following
data.result[0].id
OR
data.result[0].["id"]
The problem is, I don't know all the field names, the only field I know is the ID but there are bunch of other fields and I want to read all of them.
How do get the list of all the fields from data.result object if I don't even know each field by name?
What I have tried
1- Loop through an object's properties and get the values for those of type DateTime
My code:
foreach (PropertyInfo prop in data.result[0].GetType().GetProperties())
{
// I dont get anything
}
2- Get properties of a Dynamic Type
My code:
Dictionary<string, object> values = ((object)data.result[0])
.GetType()
.GetProperties()
.ToDictionary(p => p.Name, p => p.GetValue(data.result[0]));
3- Using PropertyDescriptor
foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(data.result[0]))
{
// I get nothing
}
None of it is working, what am I doing wrong?
As you are operating with Json, would not you consider using something like JObject instead?
JObject o = new JObject
{
{ "name1", "value1" },
{ "name2", "value2" }
};
foreach (JProperty property in o.Properties())
{
Console.WriteLine(property.Name + " - " + property.Value);
}
// name1 - value1
// name2 - value2
foreach (KeyValuePair<string, JToken> property in o)
{
Console.WriteLine(property.Key + " - " + property.Value);
}
// name1 - value1
// name2 - value2
I need to produce excel sheet from JSON object.
My JSON object is unknown and can be different from call to call. It have a simple structure (same fields in multiple rows).
I want to use the following code.
workSheet.Cells[2, 1].LoadFromCollection(dataList, false);
dataList input is List (dynamic)
Since my JSON is unknown, I can't define a class for this list (params names and types)
My question is How do I convert a JSON object dynamically to List?
for example I have json object with 3 rows to export:
dataJson -> [{"FirstName":"Yaniv","LastName":"Test","Age": 30,"SubmitDate":"2019-10-04"},{....},{....}]
I need it to be a List dataList -> Count 3
first Item:
Age 30
FirstName "Yaniv"
LastName "Test"
SubmitDate [2019-10-04]
You could deserialise your JSON into a List<Dictionary<string, object>>. For example:
var json = "[{\"FirstName\":\"Yaniv\",\"LastName\":\"Test\",\"Age\": ......]";
var data = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(json);
Now you can extract some details from this list. So to get the column names:
var columnNames = data.First().Keys.ToList();
And loop around your data like this. This will basically output in CSV format, but it should be enough to modify for your needs:
// Write out the column headers
foreach (var columnName in columnNames)
{
Console.Write(columnName + ",");
}
Console.WriteLine();
// Write out each element
foreach (var item in data)
{
foreach (var columnName in columnNames)
{
Console.Write(item[columnName] + ",");
}
Console.WriteLine();
}
This will give output something like this:
FirstName,LastName,Age,SubmitDate,
Yaniv,Test,30,2019-10-04,
Yaniv,Test,30,2019-10-04,
Yaniv,Test,30,2019-10-04,
If you're using Newtonsoft.Json you can deserialize it into a dynamic structure:
var dyn = JArray.Parse("{jsonhere...}");
Then you can read properties like that:
const string json =
"[{\"prop\": 1, \"test\": \"test!\"}, {\"prop\": 2, \"test\": \"test again!\"}, {\"prop\": 3, \"test\": \"one more!\"}]";
var parsed = JArray.Parse(json);
foreach (var value in parsed)
{
var prop = value.Value<int>("prop");
var test = value.Value<string>("test");
Console.WriteLine($"Prop: [{prop}] | Test: [{test}]");
}
Result output will be:
Prop: [1] | Test: [test!]
Prop: [2] | Test: [test again!]
Prop: [3] | Test: [one more!]
Producing excel from JSON input by LoadFromCollection was a bad idea.
The simplest and easiest solution is LoadFromDataTable by convert the JSON to a DataTable:
DataTable data = Newtonsoft.Json.JsonConvert.DeserializeObject<DataTable>(dataJson);
workSheet.Cells[1, 1].LoadFromDataTable(data,true);
Simple as that 😉
I have a list of values in an array Cmnts like
"6_12_g2_text":"22","6_12_g3_text":"33","6_12_g4_text":"44"
var CmntsValue = forms["textvalue"];
string[] Cmnts = CmntsValue.Split('{','}');
No I want to search for 6_12_g2_text and return 22 (for 6_12_g3_text and return 33). How can i achieve this?
I got the value as shown in following image!
I insert my updated code here [in second image]. Kindly check with that
The value you have is actually a JSON string. Using Json.NET you can easily parse the string into a Dictionary<string, int>, like so:
var json = "{\"6_12_g2_text\":\"22\",\"6_12_g3_text\":\"33\",\"6_12_g4_text\":\"44\"}";
var dictionary = JsonConvert.DeserializeObject<Dictionary<string, int>>(json);
And then extract any value by key:
int value;
if (dictionary.TryGetValue("6_12_g2_text", out value))
{
Console.WriteLine(value);
}
Edit:
After seeing your actual JSON string, you're going to have to do some additional work:
var json = "{\"1_3_g1_text\":\"11\"}
{\"1_3_g2_text\":\"\"}
{\"6_12_g2_text\":\"test\"}
{\"6_12_g3_text\":\"\"}
{\"1_17_g1_text\":\"works\"}
{\"5_19_g2_text\":\"submitted\"}
{\"5_19_g3_text\":\"2\"}";
var jsons = json.Split('{', '}').Where(x => !string.IsNullOrWhiteSpace(x));
var concatenatedJson = string.Format("{{{0}}}", string.Join(",", jsons));
var intermidiateDict = JsonConvert.DeserializeObject<Dictionary<string, string>>(
concatenatedJson);
Given Json input like the following:
{
"Group A": {
"Prop A": 42,
"Prop B": true,
"Prop C": [ "Hello", "World!" ]
},
"Group B": {
"Prop A": 72
}
}
I would like to populate the following data structure:
Dictionary<string, Dictionary<string, string>> Groups;
Such that the following statement would be true (differences in whitespace are not important):
Groups["Group A"]["Prop C"] == "[\"Hello\",\"World!\"]"
Inefficient Solution:
The following seems to solve this problem, but it is quite inefficient since it incurs unnecessary intermediary serialization:
Groups = new Dictionary<string, Dictionary<string, string>>();
foreach (var jsonGroup in JObject.Parse(jsonText)) {
var group = new Dictionary<string, string>();
Groups[jsonGroup.Key] = group;
foreach (var jsonProperty in jsonGroup.Value.Children<JProperty>())
group[jsonProperty.Name] = JsonConvert.SerializeObject(jsonProperty.Value);
}
Sadly JProperty.Value.ToString() seems to return odd values, for instance "False" instead of "false".
It seems that the intended behaviour of JValue.ToString() is to return the enclosed value as a string rather than encode to JSON. Instead JValue.ToString(IFormatProvider) should be used to produce a valid JSON encoded string.
https://github.com/JamesNK/Newtonsoft.Json/issues/266
However, in my particular case it seems to make better sense to retain the Json.NET representation since this avoids reparsing the same JSON content multiple times:
Groups = new Dictionary<string, Dictionary<string, JToken>>();
foreach (var jsonGroup in JObject.Parse(jsonText)) {
var group = new Dictionary<string, JToken>();
Groups[jsonGroup.Key] = group;
foreach (var jsonProperty in jsonGroup.Value.Children<JProperty>())
group[jsonProperty.Name] = jsonProperty.Value;
}
And then, instead of parsing these sub-structures with JObject.Parse I can use JToken.ToObject<T> to convert them into the desired representation:
bool myValue = Groups["Group A"]["Prop B"].ToObject<bool>();