Get List of Fields - dynamic JSON - c#

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

Related

Generating Excel file by using LoadFromCollection from a JSON object

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 😉

C# for each property get both value and name

I'm sending a JSON object through PUT from angularJS to c#, which has a property name and a value.
I'm trying to loop for each property and read both name and the value, but it fails. I have succeed to read only the name or only the value though with the below code:
Newtonsoft.Json.Linq.JObject cbpcs = pricestopsale.cbPricegroups;
foreach (string pricegroupInfo in cbpcs.Properties().Select(p => p.Value).ToList())
{
// I want to be able to do something like this inside here
if(pricegroupInfo.Value == "Something") {
// do stuff
}
}
In my above example pricegroupInfo has the value, if i change .Select(p => p.Name).ToList()) i get the name of the property.
What can I do if i want to get both name and value inside my loop ?
Update 1: The property Name is unknown to me, it's generated dynamically so I dont know in advance the property name.
Update 2: I want to be able to compare the value and the name as a string inside the loop.
Try using an anonymous object in the select.
Newtonsoft.Json.Linq.JObject cbpcs = pricestopsale.cbPricegroups;
foreach (var pricegroupInfo in cbpcs.Properties().Select(p => new { p.Value, p.Name }).ToList())
{
// read the properties like this
var value = pricegroupInfo.Value;
var name = pricegroupInfo.Name;
if(pricegroupInfo.Value.ToObject<string>() == "foo")
{
Console.WriteLine("this is true");
}
}
Reference: JObject.Properties Method
Newtonsoft.Json.Linq.JObject cbpcs = pricestopsale.cbPricegroups;
foreach (var pricegroupInfo in cbpcs.Properties())
{
if(pricegroupInfo.Name == "propName" // your property name
&& pricegroupInfo.Value.ToString() == "something") { // your value
// do stuff
}
}
As you can see, it returns IEnumerable<JProperty> which use can iterate and make use of to get property Name and Value
Try this
foreach(var prop in cbpcs.GetType().GetProperties()) {
Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(foo, null));}

select column from list

I have a List<string> where are stored database table column name.
I need to select only this column (where name is stored into list) from a c# linq query.
Is possible?
I Try this code but I don't know how I can place in select:
I try this code
items = items.ToList();
_items.Add(new FieldItem() { FieldName = "field1" });
_items.Add(new FieldItem() { FieldName = "field2" });
_items.Add(new FieldItem() { FieldName = "field3" });
_items.Add(new FieldItem() { FieldName = "field4" });
_db.Table.Where(a => a.TimeStamp > DateTime.Now.AddHours(-1)).Select(....);
Thanks
Get Dapper via NuGet.
After that put in using in your code:
using Dapper;
And you're good to go. All you would need to do now is(using the example you have posted):
using (YourDbContext _db = new YourDbContext())
{
return _db.Database.Connection.Query($"SELECT {string.Join(",", _items.Select(if => if.FieldName))} FROM Table WHERE TimeStamp > #TimeStamp;", new { TimeStamp = DateTime.Now.AddDays(-1) });
}
This methods would return IEnumerable which would have all of your fields. The results can be casted into IDictionary where the key is your column name and the value is the actual value.
So for instance, if we were to get the first row in the results with First(), we could access the field values like this:
var value = ((IDictionary<string, object>)result.First())["column_name"];
Finally, I use reflection.
In string list are stored property name.
Get a property by name, and get it's value.
In this way get all PropertyInfo for a class:
PropertyInfo[] propertyInfos;
propertyInfos = typeof(MyClass).GetProperties(BindingFlags.Public |
BindingFlags.Static);
When property name match, update property value with:
property.SetValue(child, parentProperty.GetValue(parent));
Isn't an optimized solution, but works.

Get properties of a Dynamic Type

I would like to know how to get the properties of my dynamic type.
This is the function to get the List,
var result = _files.GetFileContent(reportId).Result;
As example I get an object returned like this :
When I open it, you can see the properties I have :
The Idea is that I never know the properties. They can change over time. So I want a list which is filled with all the properties. So I can dynamically use them.
How Can I get the properties from the first item (ChargesDelta_DIFF_5, ChargesEfile_RIGHT,ChargesGecep_LEFT, etc)?
You can use reflection to get the properties out and convert it to a dictionary:
dynamic v = new { A = "a" };
Dictionary<string, object> values = ((object)v)
.GetType()
.GetProperties()
.ToDictionary(p => p.Name, p => p.GetValue(v));
If someone is still struggling with this (as I did), this might be useful.
Let's say data is the dynamic you want to list all properties from:
This worked for me
using System.ComponentModel;
...
dynamic data = new {
value1 = 12,
value2 = "asdasd",
value3 = 98,
value4 = "pgiwfj",
};
foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(data))
{
Console.WriteLine("PROP: " + prop.Name);
}
...
Then it would output:
PROP: value1
PROP: value2
PROP: value3
PROP: value4
Source: https://social.msdn.microsoft.com/Forums/vstudio/en-US/251e4f3d-ce90-444a-af20-36bc11864eca/how-to-get-list-of-properties-of-dynamic-object-?forum=csharpgeneral

Deserialize Json into list using Json.net C#

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.

Categories

Resources