Newtonsoft - How to parse an array of objects - c#

I just want to get this JSON into some kind of object. JArray and JToken are completely confusing to me.
I can create a class so that Newtonsoft knows what to map to but if you will notice the objects have the structure of: { "anAnimal": { foo: 1, bar: 2 }} and I don't know what that mapper object will look like. I'm pretty sure this should just work instantly with zero thought on my part.
var myFavoriteAnimalsJson = #"
[
{
""Dog"": {
""cuteness"": ""7.123"",
""usefulness"": ""5.2"",
}
},
{
""Cat"": {
""cuteness"": ""8.3"",
""usefulness"": ""0"",
}
}
]";
var jArray = new JArray(myFavoriteAnimalsJson);
// grab the dog object. or the cat object. HOW CUTE IS THE DOG?

With .SelectToken() to construct the JSON path query logic.
The below sample to query the first item of animals to get the object of "Dog" token and its value.
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
JArray animals = JArray.Parse(myFavoriteAnimalsJson);
var dog = animals[0].SelectToken("Dog");
Console.WriteLine(dog);
Console.WriteLine(dog["cuteness"]);
Sample Program
Output
{
"cuteness": "7.123",
"usefulness": "5.2"
}
7.123

You can deserialize it to a List<Dictionary<string, AnimalData>>
class AnimalData
{
public decimal cuteness;
public decimal usefulness;
}
var myFavoriteAnimalsJson = #"
[
{
""Dog"": {
""cuteness"": ""7.123"",
""usefulness"": ""5.2"",
}
},
{
""Cat"": {
""cuteness"": ""8.3"",
""usefulness"": ""0"",
}
}
]";
var results = JsonConvert.DeserializeObject<List<Dictionary<string, AnimalData>>>(myFavoriteAnimalsJson);
Now each list item contains a dictionary with a single key of Dog Cat...

If you start from a serialized JSON, i.e. a string, you have to parse it:
var jArray = JArray.Parse(myFavoriteAnimalsJson);

Related

Deserializing JSON issue

I need to deserialize just part of a JSON string returned from a server. The 'myData' portion in the JSON string below.
My JSON string is structured as follows.
{
"data": {
"CODE": {
"someData": {
"h": "foo",
"id": "City",
"lat": "11.11111"
},
"feedMe": [
[
{
"myData": {
"item1": "a",
"item2": "b",
"item3": "c"
},
"moreData": {}
}
]
]
}
}
}
In Unity there is the JSONutility.FromJson method
https://docs.unity3d.com/ScriptReference/JsonUtility.FromJson.html
but unsure how I would either
1 pass only the 'myData' portion to this method.
or
2 Deserialize the entire string
An alternativ to using JsonUtility there is good old SimpleJSON which allows you to only access a certain field of your json like e.g.
var N = JSON.Parse(the_JSON_string);
var myData = N["data"]["CODE"]["feedMe"][0][0];
var item2 = myData["item2"].Value;
In general the simplest way to get the needed c# class structure for your json is always using json2csharp and make all classes [Serializable] and remove the {get; set;} in order to use fields instead of properties. Something like this
[Serializable]
public class SomeData
{
public string h;
public string id;
public string lat;
}
[Serializable]
public class CODE
{
public SomeData someData;
public List<List<MyData>> feedMe;
}
[Serializable]
public class MyData
{
public string item1;
public string item2;
public string item3;
}
[Serializable]
public class Data
{
public CODE CODE;
}
[Serializable]
public class RootObject
{
public Data data;
}
Instead of List<T> you can also use T[] if you like. And the class names actually don't matter but the structure and field names have to match.
and then use
var root = JsonUtility.FromJson<RootObject>(THE_JSON_STRING);
var myData = root.data.CODE.feedMe[0][0];
var item2 = myData.item2;
As already comented however there is a nested array in your array .. not sure if this is intended.
well, use one of the powerful json nuget -newtonsoft.json , then in your code you can iterate the values like below
var files = JObject.Parse(YourJSON);
var recList = files.SelectTokens("$..data").ToList();
foreach (JObject obj in recList.Children())
{
foreach (JProperty prop in obj.Children())
{
var key = prop.Name.ToString();
var value = prop.Value.ToString();
//Do your stuffs here
}
}
JsonUtility not work whit json files, this only for save and load basic public variables of some class. Asset Store have many frameworks for parse json. p.s. your json is strange, [] its array and you have feedMe:[[{myData, moreData}]]. One array whene just one object in array... parse confusing.

How to address an object from a json array

Using the JSON library, I've imported an array of objects:
dynamic serviceList = JsonConvert.DeserializeObject(listString)
I've got an array of json objects, each has the property "name".
[
{
"name":"abcd",
"properties":{
"type":"1234"
}
},
{
"name":"xyz",
"properties":{
"type":"aaaa"
}
}
]
How do I address just the object "abcd"?
You can parse your json Array using Newtonsoft.Json JArray.Parse() function.
Use FirstOrDefault() to get record where name is "abcd"
string listString = #"[{'name': 'abcd','properties': {'type': '1234'}},{'name': 'xyz', 'properties': { 'type': 'aaaa'}}]";
JArray jArray = JArray.Parse(listString);
//FirstOrDefault to get first record which satisfy the condition
var result = jArray.FirstOrDefault(x => (string)x["name"] == "abcd");
Console.WriteLine(result);
Output:
{
"name": "abcd",
"properties": {
"type": "1234"
}
}
.Net Fiddle
The right way to solve the problem is create a static Object
Public Obj1 {
public string name {get;set;}
public Properties properties {get;set;}
}
Public Properties {
public string type {get;set;}
}
Then you can deserialize the JSON into a List<Obj1>, in this way you can iterate your list and find the "name":"abcd" Object. var myobj = mylist.FirstOrDefault(x=> x.name == "abcd")
You can use the dynamic to do pretty much anything you would like it to do, so nothing would stop you from evaluating your result in the following way:
dynamic selectionList = JsonConvert.DeserializeObject( json );
foreach (var item in selectionList) {
if ( string.Equals( (string)item.name, "abcd", StringComparison.OrdinalIgnoreCase ) ) {
Console.WriteLine( item );
}
}
This would work as per your original request, but I think you are making it a lot harder on yourself than need be :)
To see how this works, you could check this dotnetfiddle
I would probably create a class based on the spec, but I am assuming that properties is a dynamic list of properties and their values, meaning you would still end up with a Dictionary<string, object> in the end
You can access it like this:
for (int i = 0; i < serviceList.Count; i++)
{
if (serviceList[i].name == "abc")
{
DoSomethingWith(serviceList[i];
break;
}
}
Edit: didn't see that you wanted the "abc" element, so modified the code accordingly.
This will get the value for you as a JObject, from which you can access the contained values:
var serviceList = JArray.Parse(listString);
var target = serviceList.Single(s => s["name"].ToString() == "abcd");
if (target != null)
{
var type = target["properties"]["type"];
// etc
}

json to C# objects

I receive a JSON string from a external system and I want to turn in to C# objects. The problem is that the "CAR" objects are unique in the string and I do not know how many there is (0 to many).
Now, It doesn't make sense to hardcode classes for each "CAR" like class: CAR1, class: CAR2 and so on. I tried to create a general CAR class and was thinking I could loop throu the JSON and create CAR objects.
The problem is that I cant't identify and find each CAR dynamically.I find the attributes and values for "CAR1" by hardcode "CAR1".
I would like to find a solution like:
foreach(item.key where key starts with "CAR")
Tried the following:
var expConverter = new ExpandoObjectConverter();
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(jsondata, expConverter);
dynamic json = Newtonsoft.Json.JsonConvert.DeserializeObject(jsondata);
foreach (var itm in obj)
{
string s = itm.Key;
if(s.StartsWith("CAR"))
{
CarObj = new Car();
CarObj.HP = json.CAR1[0].HORSEPOWER[0];
CarObj.COLOR = json.CAR1[0].COLOR[0];
// Would like to use something like
// CarObj.HP = json.**item.key**[0].HORSEPOWER[0];
}
}
{
"CAR1": [{
"HORSEPOWER": ["180", "int", "Hp"],
"COLOR": ["GREEN", "string", "COLOR"]
}],
"CAR2": [{
"HORSEPOWER": ["200", "int", "Hp"],
"COLOR": ["BlUE", "string", "COLOR"]
}]
}
You're not forced to use dynamic right away. First use the strongly-typed APIs to find the right portion of the JSON, then switch to dynamic:
var obj = JObject.Parse(json);
foreach (var element in obj)
{
if (element.Key.StartsWith("CAR"))
{
dynamic value = element.Value;
var carObj = new Car();
carObj.HP = value[0].HORSEPOWER[0];
}
}
You can deserialize as Dictionary<string,List<CarDetails>>
public class CarDetails
{
public List<string> HORSEPOWER { get; set; }
public List<string> COLOR { get; set; }
}
and then iterate the dictionary to get the results.

Deserialize array in JSON into class/object

I'm trying to store JSON data into a class. I could deserialize my otherJSON string into class by: var ser = JsonConvert.DeserializeObject<ClsResult>(myJSON); before I got stuck with array.
{
\"Test\": [{
\"FirstBool\":1,
\"aString\":\"hello\"
}]
}
This is my class for JSON:
public class Test
{
[JsonProperty("FirstBool")]
public bool FirstBool { get; set; }
[JsonProperty("aString")]
public string aString { get; set; }
}
public class ResultObject
{
[JsonProperty("Test")]
public List<Test> Test { get; set; }
}
How I deserialize my non-array JSON:
var ser = JsonConvert.DeserializeObject<ResultObject>(myJSON);
What changes do I need to make it work again?
Edited answer
Your json string as I've noticed later contains object named Test which is basically an array of objects ( object[] ).
As you can see from the json string :
{
"Test": [{
"FirstBool" : 1,
"aString" : "hello"
}]
}
[ means that json object begins an array type and ] means that json object ended an array type.
{ means that json object begins an object type and } means that json object ended an object type.
Which in your case will require to make kind of a custom deserializer using existing methods from Newtonsoft.Json library.
Example for the Test object could be :
JObject obj = JObject.Parse(jsonString);
// now your obj contains field named "Test" that is of type object[]
// to retrieve informations you have to select "Test" token
JToken testToken = obj.SelectToken("Test");
// your token contains now something like " [{ "FirstBool" : 1, "aString" : "hello" }]"
// which basically is an array
// meaning that you have to iterate through this
foreach(var child in token.Children())
{
// and convert it to a Test object
Test test = JsonConvert.DeserializeObject<Test>(child.ToString());
// test now is fully deserialized object
}
Deserialize it as a list:
JsonConvert.DeserializeObject<List<Test>>(json);
...instead of a wrapper object.

Using JSON.NET to access JSON attributes to create a C# dictionary

I want to convert what is ultimately a dictionary in JSON to a C# dictionary without much ado.
Am I barking up the wrong tree by using the JSON.NET library here? The JArray class doesn't want to give me anything to access the attribute (only the value) ie it tells me the value but never the "key".
I can't quite believe no one else would find this limiting, so am assuming I'm missing something. My muddled attempt is this:
Given this json:
{
"appSettings" : [
{"rows": "5"},
{"columns" : "7"}
]
}
I would like to select this into a dictionary like this:
var dict = jsonObject["appSettings"].Select(s => new
{
key = s.Name, // wish this property existed
value = s.Value // wish this property existed
}).ToDictionary(s => s.key, s => s.value);
This is my UnitTest:
[Test]
public void CanLoadJsonAppSettings()
{
var json = #"
""{appSettings"" : [
{""ViewRows"" : ""1""},
{""ViewColumns"" : ""2""}
]}";
var dict = CreateJsonDictionary(json);
Assert.That(dict.Count, Is.EqualTo(2));
}
public CreateJsonDictionary(string jsonText)
{
var jsonObject = JObject.Parse(jsonText);
return jsonObject["appSettings"].Select(s => new
{
key = s.Name,
value = s.Value
}).ToDictionary(s => s.key, s => s.value);
}
EDIT: Thanks to #jim, we are a little closer.
For completeness, I will document the slightly awkward step I needed in order to get at the object I needed:
I had to change my JSON.
Instead of using an array (as in the code above) I used a more simple/truer dictionary:
var json = #"
{
""appSettings"" : {
""ViewRows"" : ""1"",
""ViewColumns"" : ""2""
}
}";
Then I had to Parse, get a JSON JObject, then convert back to a string, and then Deserialize:
var jo = JObject.Parse(jsonText);
var appSettings = jo["appSettings"];
var appSettings = JsonConvert.DeserializeObject<Dictionary<string, string>>(appSettings.ToString());
So part of my problem, was getting JSON confused.
Even so, if there is a more elegant way to do this, I'm all ears.
EDIT2: I still had to solve the original problem above, converting a JSON array to a dictionary. Once my JSON is corrected to contain proper name/value pairs:
"connectionStrings": [
{"name" : "string1", "value" : "value1"},
{"name" : "string2", "value" :"value2"},
]
This is the code that solved it (nb it looks a lot like my original attempt):
var jsonObj = JObject.Parse(jsonText);
var conStrings = jsonObj.Properties().Select(s =>
new {
key = s.Name,
value = s.Value.ToString()
}).ToDictionary(s => s.key, s => s.value);
And this only works if you have no other arrays.
Panda,
Verbatim from james newton king himself on SO to a similar question:
// Json.NET does this...
string json = #"{""key1"":""value1"",""key2"":""value2""}";
Dictionary<string, string> values
= JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
you can find the thread here:
How can I deserialize JSON to a simple Dictionary<string,string> in ASP.NET?
hope this helps (tho not 100% certain on how this works with complex tree structures)
This is the MS way to do this, but it's quite complex and I really think than YvesR's solution might be easier to implement.
http://atsung.wordpress.com/2008/08/07/javascriptserializer-example/
To convert js assosiative array into dictionary, use may use converter which is as follows:
using System;
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace MyJsonConverters
{
public class AssosiativeArrayConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType.GetInterface(typeof(IDictionary<,>).Name) != null;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject jObject = JObject.Load(reader);
var result = Activator.CreateInstance(objectType);
var addMethod = result.GetType().GetMethod("Add");
var dictionaryTypes = objectType.GetGenericArguments();
foreach (JProperty property in jObject.Properties())
{
var key = Convert.ChangeType(property.Name, dictionaryTypes[0]);
var value = serializer.Deserialize(property.Value.CreateReader(), dictionaryTypes[1]);
addMethod.Invoke(result, new[] { key, value });
}
return result;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
}
then usage is as follows:
Dictionary<string, string> dictionary;
dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(value, new AssosiativeArrayConverter);
where T is your Dictionary e.g. Dictionary or whatever you like.
Json which is deserialized in my case looks like follows:
{
"MyDictionary": {
"key1": [
"value1",
"value2",
"value3"
],
"key2": [ ]
}
I know it is not a proper answer direct to your question, but for all JSON stuff in C# here is the link for the a very good library you can use to easy do anything with JSON in C#.
http://james.newtonking.com/pages/json-net.aspx

Categories