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.";
Related
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
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}
{
"_id": "underscore",
"_rev": "136-824a0ef7436f808755f0712c3acc825f",
"name": "underscore",
"description": "JavaScript's functional programming helper library.",
"dist-tags": {},
"versions": {
"1.0.3": {
"name": "xxx",
"description": "xxx"
},
"1.0.4": {},
"1.1.0": {}
}
}
I would like to retrieve the latest version(1.1.0) from the json file. However, it always gives out me errors of "can not deserialize json object into type RootObject
Here is my class
public class versions
{
public string name { get; set; }
public string description { get; set; }
}
public class RootObject
{
public List<versions> vs { get; set; }
}
And here is where I used it
RootObject[] dataset = JsonConvert.DeserializeObject<RootObject[]>(json);
Any idea. Many thankx
Update:
I have updated the JSON file format, but some problem..
I think the problem is, that in JSON you have to quote all "field"/attribute names. (Thats a difference from standard Javascript-Notation, where you can have unquoted attributes).
So, your file should be like:
{
"_id" : "underscore",
"versions": {
"1.0.3" : {
"name": "xxx",
"description": "xxx"
}
}
Note that {1.0.3: { name: "xxx" } } wouldn't be valid JavaScript either since '1.0.3' is an invalid identifier in JavaScript.
Looking at the JSON in your updated answer:
{
"_id" : "underscore",
"versions": {
"1.0.3" : {
"name": "xxx",
"description": "xxx"
},
"1.0.4" : {
"name": "xxx",
"description": "xxx"
}
}
This is still Invalid JSON - you have 4 opening { and only 3 closing }
you should use http://jsonlint.com/ - to validate your JSON and ensure it is Valid
I've fixed your json in question. Now for your real question
I would like to retrieve the latest version(1.1.0) from the json file. However, it always gives out me errors of "can not deserialize json object into type RootObject
You have property names like 1.0.3 that are unknown at compile time. So you can not deserialize them to a concrete class. You should handle them dynamically.
Try this:
var versions = JObject.Parse(json)["versions"]
.Children()
.Cast<JProperty>()
.ToDictionary(c => c.Name, c => c.Value.ToObject<versions>());
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());
I know this is not hard, but I've been staring at the JSON.Net documentation for a half hour and don't see how it works. I've got it setup, but my initial attempts are failing and the documenation that I have looked at so far isn't making it obvious (to me, at least) how to deserialize the array form response.data and then get at the individual fields of each record.
Also, I don't need to use JSON.Net - it just seemed like a good choice. Any solution will do just fine.
{
"request":{
"Format":"json",
"Target":"Affiliate",
"Method":"findAll",
"Service":"HasOffers",
"Version":"2",
"NetworkId":"directagents",
"NetworkToken":"......"
},
"response":{
"status":1,
"data":{
"2056":{
"Affiliate":{
"id":"2056",
"company":
"123 Greetings 123 Greetings (CD186)",
"address1":"1 Change Address",
"address2":"",
"city":"City",
"region":"NY",
"country":"US",
"other":null,
"zipcode":"11111",
"phone":"-",
"fax":null,
"website":null,
"signup_ip":null,
"date_added":"2012-02-24 18:00:24",
"modified":-62169966000,
"ref_id":"CD186",
"status":"pending",
"wants_alerts":"1",
"account_manager_id":"20",
"payment_method":"check",
"payment_terms":"net 30",
"w9_filed":"0",
"referral_id":null,
"affiliate_tier_id":null,
"fraud_activity_score":null,
"fraud_activity_alert_threshold":null,
"fraud_activity_block_threshold":null,
"fraud_profile_alert_threshold":null,
"fraud_profile_block_threshold":null,
"scrub_offer_pixels":null,
"shared":"0"
}
},
"1606":{
.......this is enough to see how its structured....
You could model that “array” as Dictionary<int, AffiliateHolder>. The classes for that JSON could look like this:
class Top
{
public Request Request { get; set; }
public Response Response { get; set; }
}
class Request
{
public string Format { get;set; }
// etc.
}
class Response
{
public int Status { get; set; }
public Dictionary<int, AffiliateHolder> Data { get; set; }
}
class AffiliateHolder
{
public Affiliate Affiliate { get; set; }
}
class Affiliate
{
public int Id { get; set; }
// etc.
}
var o = JsonConvert.DeserializeObject<Top>(myJSONString);
The fastest, easiest way is to use Json.NET and LINQ to Json. Given your example above, the following code:
var parsedJson = JObject.Parse(rawJson);
foreach (var item in parsedJson["response"]["data"])
{
Console.WriteLine(item.ToString());
}
would write out the following to the console:
"2056": {
"Affiliate": {
"id": "2056",
"company": "123 Greetings 123 Greetings (CD186)",
"address1": "1 Change Address",
"address2": "",
"city": "City",
"region": "NY",
"country": "US",
"other": null,
"zipcode": "11111",
"phone": "-",
"fax": null,
"website": null,
"signup_ip": null,
"date_added": "2012-02-24 18:00:24",
"modified": -62169966000,
"ref_id": "CD186",
"status": "pending",
"wants_alerts": "1",
"account_manager_id": "20",
"payment_method": "check",
"payment_terms": "net 30",
"w9_filed": "0",
"referral_id": null,
"affiliate_tier_id": null,
"fraud_activity_score": null,
"fraud_activity_alert_threshold": null,
"fraud_activity_block_threshold": null,
"fraud_profile_alert_threshold": null,
"fraud_profile_block_threshold": null,
"scrub_offer_pixels": null,
"shared": "0"
}
}
It is not necessary to create concrete classes for explicit deserialization. Obviously that is a perfectly valid approach, however, if that's your style preference.
See http://james.newtonking.com/projects/json/help/LINQtoJSON.html for more examples.
I think you can try creating a simple example, not a huge json like that one.
Take a look at http://servicestack.net/ it is an alternative to Json.NET, it is faster and the learning curve is small. You can find a lot of examples on the website.
Is this in javascript? You should be able to just do this:
JSON.parse(response.data)