Sort Dynamic Object by DateTime c# - c#

From an API response, I get a JArray result:
dynamic Backups = JArray.Parse(result.Content.ReadAsStringAsync().Result.ToString());
Backups variable holds the result for me as dynamic. Here is an example of the result I get:
[{
"bu_region": "US",
"created_at": "2022-01-04 00:06:09",
"is_automate": "0",
"bu_snapshot_name": "null",
"plugin_v": "4.5.2",
},
{
"bu_region": "US",
"created_at": "2022-02-20 00:07:55",
"is_automate": "0",
"bu_snapshot_name": "null",
"plugin_v": "4.5.2",
},
{
"bu_region": "US",
"created_at": "2021-12-31 00:05:31",
"is_automate": "0",
"bu_snapshot_name": "null",
"plugin_v": "4.5.2",
}]
I would like to sort the Dynamic Result above by DateTime, and then, I show the result in my form application,
On the form after adding the above result data to an Object, I can sort it using below code:
List<Cards> sortedListByDate = listCards.OrderBy(s => s.DateOfCreation.Date).ToList();
Cards, is my Custom Class and it inherits from Panel Object/Class
namespace WinFormsApp1
{
public class Cards : Panel
{
public DateTime DateOfCreation { get; set; }
public TimeSpan TimeOfCreation { get; set; }
public Cards()
{
}
}
}
Sorting Cards object works perfectly, however, due to the dynamic functions I use, I have lot of trouble adding some handlers, and would like to sort the API result before adding its data to the Cards Object in my AppForm.
In Short, I would like to sort the Data stored at Backups by created_at
Thank you in Advance for any input.

I found my answer after some research.
Here is an easy way that worked for me:
using System;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public class Program
{
public static void Main()
{
string json = #"
[{
""bu_region"": ""US"",
""created_at"": ""2022-01-04 00:06:09"",
""is_automate"": ""0"",
""bu_snapshot_name"": ""null"",
""plugin_v"": ""4.5.2"",
},
{
""bu_region"": ""US"",
""created_at"": ""2022-02-20 00:07:55"",
""is_automate"": ""0"",
""bu_snapshot_name"": ""null"",
""plugin_v"": ""4.5.2"",
},
{
""bu_region"": ""US"",
""created_at"": ""2021-12-31 00:05:31"",
""is_automate"": ""0"",
""bu_snapshot_name"": ""null"",
""plugin_v"": ""4.5.2"",
}]";
JArray array = JArray.Parse(json);
JArray sorted = new JArray(array.OrderBy(obj => (DateTime)obj["created_at"]));
Console.WriteLine(sorted.ToString(Formatting.Indented));
}
}
You can test it here:
https://dotnetfiddle.net/4Y96OZ

Related

How can I access my nested data using variables C#

I have a json file and I deserialised it as shown in the code below. Some context, dex is a robot and it has information such as battery and so on as shown in the json file below. I want to read the battery status for the robot that the user selected ( robot).
This is my code, currently im only accessing data.dex but i want to change it to whichever data.robot, where robot is a variable
var data = JsonConvert.DeserializeObject<Root>(json);
var robot = queryDetails2.Amr;
var text =$"";
if (data.dex.battery.status == "good")
{
text = $"{queryDetails2.Amr}'s battery is in good condition. ";
}
This is the json file:
{
"dex":
{
"current_job":
{"job":null, "task": null, "location": null},
"battery":
{"name":"battery", "status": "good", "value": "100"},
},
"dex_1":
{
"current_job":
{"job":null, "task": null, "location": null},
"battery":
{"name":"battery", "status": "good", "value": "100"},
},
"dex_2":
{
"current_job":
{"job":null, "task": null, "location": null},
"battery":
{"name":"battery", "status": "good", "value": "100"},
}
}
I wanted to use the GetMethod or the solution as suggested in this question (https://stackoverflow.com/questions/53076743/how-to-access-variable-of-a-nested-functions-in-python[1]).
However, im getting errors like it does not have a method. Now im confused, was it because i used var? but the deserialised method converts the json to an object though..
Anyway, how should i approach this?
Assuming that you have 3 robots with different names: dex, dex_1 and dex_2, you should reorganize your solution to treat the json data as a list of Robots instead of 3 separate variables for each robot.
To do this, first your json should look like this:
{
"robots":[
{
"name":"dex",
"current_job":{
"job":null,
"task":null,
"location":null
},
"battery":{
"name":"battery",
"status":"good",
"value":"100"
}
},
{
"name":"dex_1",
"current_job":{
"job":null,
"task":null,
"location":null
},
"battery":{
"name":"battery",
"status":"good",
"value":"100"
}
},
{
"name":"dex_2",
"current_job":{
"job":null,
"task":null,
"location":null
},
"battery":{
"name":"battery",
"status":"good",
"value":"100"
}
}]
}
Next, update your serialization classes. Add a field called name in the Robot class or whatever class type you currently have for data.dex. In Root, remove the "dex" fields and add a List<Robot>.
public class Root
{
public List<Robot> robots { get; set; }
}
public class Robot
{
public string name { get; set; }
public Job current_job { get; set;}
public Battery battery{ get; set; }
}
Now you can write whatever logic to get the right robot data. Here is an example using System.Linq:
var robotName = "dex_2";
var robotInfo = data.robots.First(x => x.name.Equals(robotName));
var text = $"{robotName}'s battery is in {robotInfo.battery.status} condition.";

Deserializing JSON array with Unity JsonUtility fails to get serialized values

I'm trying to deserialize card information from a JSON to be used in a Unity game, but it's not working quite right. I've tested the classes I'm trying to deserialize to, and I can manually create objects for them, but the deserializer doesn't create them correctly.
When I run the deserializing logic, the resulting array is the correct size, but none of the Cost or Name fields of the cards fill in and I'm left with an array of uninitialized Card objects.
The relevant code I have is as follows:
The file where we deserialize, Game.cs:
using System.IO;
using UnityEngine;
public class Game {
private CardsCollection allCards;
private void LoadJson()
{
...
// Find the path to our JSON file
// Save the path as "path"
// I have verified this line gets the correct json data as a string
string json = File.ReadAllText(path);
// Convert the json string into a deserialized array of objects
// using the CardsCollection wrapper
allCards = JsonUtility.FromJson<CardsCollection>(json);
}
}
The Card object file, Card.cs:
using System;
[Serializable]
public class Card
{
public string Name { get; set; }
public int Cost { get; set; }
public Card(string Name, int Cost)
{
this.Name = Name;
this.Cost = Cost;
}
}
[Serializable]
public class CardsCollection
{
public Card[] cards;
}
And finally the JSON itself:
{
"cards": [
{
"Name": "copper",
"Cost": 0
},
{
"Name": "silver",
"Cost": 3
},
{
"Name": "gold",
"Cost": 6
},
{
"Name": "curse",
"Cost": 0
},
{
"Name": "estate",
"Cost": 2
},
{
"Name": "duchy",
"Cost": 5
},
{
"Name": "province",
"Cost": 8
}
]
}
The Json serialization can only handle fields (see supported types https://docs.unity3d.com/Manual/JSONSerialization.html) but your Name and Cost look like properties What is the difference between a field and a property?
Since they are marked public and can be accessed directly anyway I would just remove the {get; set}

Deserialize only one property of a JSON file

I am faced with a problem.
I want to deserialize a complex JSON response from a server, but I only need one part of it.
Here is an example:
{
"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
]
}
}
}
I also used Csharp2json to get the class objects that I need, I just modified the menu class according to my needs :
public class Menuitem
{
public string value { get; set; }
public string onclick { get; set; }
}
public class Popup
{
public IList<Menuitem> menuitem { get; set; }
}
public class Menu
{
public Popup popup { get; set; }
}
public class RootObjectJourney
{
public Menu menu { get; set; }
}
Now, how do I deserialize if I only need the popup value and his children?
You can actually utilize the Linq namespace of the NewtonSoft.Json and modify your code little bit to get only the "popup" elements from the JSON.
your class structure remains the same. Make sure you use the namespace(s)
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
then in your code once you have the JSON string with you, you can use the "JObject" static method "Parse" to parse the JSON, like
var parsedObject = JObject.Parse(jsonString);
This will give you the JObject with which you can access all your JSON Keys just like a Dictionary.
var popupJson = parsedObject["menu"]["popup"].ToString();
This popupJson now has the JSON only for the popup key.
with this you can use the JsonConvert to de- serialize the JSON.
var popupObj = JsonConvert.DeserializeObject<Popup>(popupJson);
this popupObj has only list of menuitems.
If you do not use Newtonsoft and are using System.Text.Json in .NET Core, you can use this:
var post = JsonDocument.Parse(stringifiedJson);
var cat = post.RootElement.GetProperty("category").GetString();
You see GetString here to cast the value to string, there are other overloads available to cast the json value to Int32 etc.
If the intend is to deserialize only one property, I generally perefer to use JsonPath due to its flexibility. Please check the code below
var jsonQueryString = "{ 'firstName': 'John',
'lastName' : 'doe',
'age' : 26,}";
JObject o = JObject.Parse(jsonQueryString);
JToken token= o.SelectToken("$.age");
Console.WriteLine(token);
If your Json is complex, you can use power of JsonPath.
you can check https://support.smartbear.com/readyapi/docs/testing/jsonpath-reference.html#examples for JsonPath detailed documentation and examples.
I also included example below for further usage information:
JObject o = JObject.Parse(#"{
'store': {
'book': [
{
'category': 'history',
'author': 'Arnold Joseph Toynbee',
'title': 'A Study of History',
'price': 5.50
},
...
]
},
'expensive': 10
}");
//gets first book object
Console.WriteLine(o.SelectToken("$..book[0]"));
//get first book's title
Console.WriteLine(o.SelectToken("$..book[0].title"));
// get authors of the books where the books are cheaper then 10 $
foreach (var token in o.SelectTokens("$..[?(#.price < 10)].author"))
Console.WriteLine(token);
.NET 5+
The solution is very simple:
using System.Text.Json;
var doc = JsonDocument.Parse(response.Content);
var popupJson= doc.RootElement.GetProperty("menu").GetProperty("popup");

Show json data in view in ASP.NET MVC3?

I am developing facebook app in which i am fetching user's friend detail in as
dynamic result = client.Get("me/friends"); //it gives friend's data for id, name
it gives data in
{
"data": [
{
"name": "Steven",
"id": "57564897"
},
{
"name": "Andy",
"id": "8487581"
}
}
Now i would like to parse this data and store it. so that i can use it my way.
I was trying to parse it using JSON.NET and show the data in view as
var model = JsonConvert.DeserializeObject<FriendDetail>(result.data);
in the class :
public class FriendDetail
{
public string id { get; set; }
public string name { get; set; }
public FriendDetail(string i, string n)
{
id = i;
name = n;
}
}
Now so that i can pass the view as "return View(model)"
But its giving me error: The best overloaded method match for 'Newtonsoft.Json.JsonConvert.DeserializeObject<FBApp.Models.FBFriendDetail>(string)' has some invalid arguments
Why this error is occurring ?
Please help me to parse this json data.
Also is there any better way to parse and Store json data and also then show in view ?
Please help
You are trying to deserialize a list of FriendDetail objects into a single FriendDetail object. Try the following:
var jObject = JObject.Parse(result.ToString());
var model = JsonConvert.DeserializeObject<List<FriendDetail>>(jObject["data"].ToString());
EDIT
This is how I tested it:
var result =
#"{
""data"": [
{
""name"": ""Steven"",
""id"": ""57564897""
},
{
""name"": ""Andy"",
""id"": ""8487581""
}]
}";
var jObject = JObject.Parse(result.ToString());
var model = JsonConvert.DeserializeObject<List<FriendDetail>>(jObject["data"].ToString());

How to create the Google DataTable JSON expected source using C#?

How can I create the JSON source expected by the google.visualization.datatable using C#? Obviously using the JavaScriptSerializer is out of the question since the expected JSON has a weird structure as described on the documentation:
var dt = new google.visualization.DataTable(
{
cols: [{id: 'task', label: 'Task', type: 'string'},
{id: 'hours', label: 'Hours per Day', type: 'number'}],
rows: [{c:[{v: 'Work'}, {v: 11}]},
{c:[{v: 'Eat'}, {v: 2}]},
{c:[{v: 'Commute'}, {v: 2}]},
{c:[{v: 'Watch TV'}, {v:2}]},
{c:[{v: 'Sleep'}, {v:7, f:'7.000'}]}
]
},
0.6
)
Though I'm not familiar in the .NET environment, there is a .NET helper for the Google Visualization API called bortosky-google-visualization. The library writes a JSON Google DataTable from a System.Data.DataTable object.
Another way to achieve this is to use the Google DataTable .Net Wrapper (https://googledatatablelib.codeplex.com/) which gives a possibility to work with a strongly typed System.DataTable that can then be converted into the google.datatable visualization JSON format.
This server side code
public string GetStatisticsForChart(string messageCode)
{
//some repository that returns data....
var data = _statisticsRepository.GetPerMessage(messageCode);
//It simply returns a list of objects with Year and Count properties.
var query = (from t in data
group t by new {t.TimeStamp.Year}
into grp
select new
{
grp.Key.Year,
Count = grp.Count()
}).ToList();
//let's instantiate the DataTable.
var dt = new Google.DataTable.Net.Wrapper.DataTable();
dt.AddColumn(new Column(ColumnType.String, "Year", "Year"));
dt.AddColumn(new Column(ColumnType.Number, "Count", "Count"));
foreach (var item in query)
{
Row r = dt.NewRow();
r.AddCellRange(new Cell[]
{
new Cell(item.Year),
new Cell(item.Count)
});
dt.AddRow(r);
}
//Let's create a Json string as expected by the Google Charts API.
return dt.GetJson();
}
would generate the following JSON output
{
"cols": [
{"type": "string", "id": "Year", "label": "Year"},
{"type": "number", "id": "Count", "label": "Count"}
],
"rows": [
{"c": [{"v": "2011"}, {"v": "1860"}]},
{"c": [{"v": "2012"}, {"v": "2000"}]}
]
}
and this can be used either in Asp.NET WebAPI or directly in the ASP.NET MVC controller.
The expected JSON in the example above is not JSON but a Javascript object literal. JSON is only a subset of Javascript object literal notation, but the example above should (and does) also work, if the Google DataTable is initialized with a similar looking JSON. (To get proper JSON just put double quotes around the keys.)
So actually you can use the DataContractJsonSerializer or JavaScriptSerializer to construct JSON for the Google DataTable. However, if your starting point is a System.Data.DataTable it is probably easier to use the library mentioned in the answer above.
The best way to create google charts datatable via c# is to iterate data and fill model class and return filled model as JSON , here is the model representation :-
public class GChartsDataTbl
{
public List<Col> cols { get; set; }
public List<Row> rows { get; set; }
}
public class Col
{
public string id { get; set; }
public string type { get; set; }
}
public class C
{
public string v { get; set; }
public object f { get; set; }
}
public class Row
{
public List<C> c { get; set; }
}

Categories