Deserialize array in JSON into class/object - c#

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.

Related

Newtonsoft - How to parse an array of objects

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);

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.

Json is not deserializing correctly into a class

I'm trying to convert an array into a class. So I get the array, then serialize it with JsonConvert as you can see below:
var gameResponse = GetGame(Id);
var returnedArray = gameResponse.Result.Results;
var json = JsonConvert.SerializeObject(returnedArray);
var result = JsonConvert.DeserializeObject<T>(json);
I can see the results of this in Visual Studio debug mode and "json" looks like this:
[
{
\"CreatorId\":\"41c5321e-6f37-4d4f-92f7-fc381be0fc62\",
\"GameId\": \"3938\",
\"Type\": \"2\",
\"CreateDate\": \"1/2/2017\",
\"TeamId\": \"2394\",
\"LeaderId\": \"34922\",
\"CountryCode\": \"23\",
\"SalesRank\": \"4\",
\"Title\": \"Space Shooter Max\",
\"TeamName\": \"The One\",
\"TeamMembers\" : \"4\"
}
]
However, when the code hits the next line:
var result = JsonConvert.DeserializeObject<T>(json); // In this case, <T> is <Game>
I get this error:
JsonSerializationException: Cannot deserialize the current JSON array
(e.g. [1,2,3]) into type 'GameLabs.Game' because the type requires a
JSON object (e.g. {"name":"value"}) to deserialize correctly.
GameLabs.Game is a class that looks like this:
public sealed class Game
{
public string CreatorId { get; set; }
public string GameId { get; set; }
public string Title { get; set; }
public DateTime CreateDate { get; set; }
public string CountryCode { get; set; }
}
I'm not sure why it won't accept the JSON.
Does anyone see anything wrong?
Thanks!
If you examine your JSON, it is not an a single object, but instead a collection. "[..]" signifies a collection.
For example,
[ "Ford", "BMW", "Fiat" ]
The above Json implies a array of string with 3 elements. This is similar to your Json as well.
Hence you need to deserialize your Json to a Collection as well.
var result = JsonConvert.DeserializeObject<List<T>>(str);
You can read more on Json Arrays here
As I can see, your JSON is array and you should write somethink like this:
var result = JsonConvert.DeserializeObject<T[]>(json);
T=>T[]

Able to deserialize string type but not object type

I am using C# with JSON.NET. Below are the two types.
JSON object - var user = { "name": "test", "title": "mytitle"};
JSON String - var user1 = "{ \"name\": \"test\", \"title\": \"mytitle\" }";
Using Newtonsoft.Json to deserialize the JSON object. C# Code in which I am handling JSON.
public class sampledata
{
[JsonProperty("name")]
public string name { get; set; }
[JsonProperty("title")]
public string title { get; set; }
}
public void SampleEvent(string param)
{
sampledata s = JsonConvert.DeserializeObject<sampledata>(param);
}
When I got JSON String in param the deserialization is fine. But when I got JSON object in param - First error I am getting is
"Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'UCRS.MainWindow+sampledata' because the type requires a JSON object
(e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g.
{"name":"value"}) or change the deserialized type to an array or a
type that implements a collection interface (e.g. ICollection, IList)
like List that can be deserialized from a JSON array.
JsonArrayAttribute can also be added to the type to force it to
deserialize from a JSON array.
Path '', line 1, position 1.
So I changed the code as :
List<sampledata> s = JsonConvert.DeserializeObject<List<sampledata>>(param);
Then I am facing different issue
" Unexpected character encountered while parsing value: o. Path '',
line 1, position 1."
When some event is raised in web page I am handling that event in c# using webbrowser objectforscripting. I always get the JSON object as param. How to deserialize JSON object in C#? Please help
Its pretty simple..working for both
string jsonObject = #"{""name"":""test"",""title"":""mytitle""}";
var jsonString = "{ \"name\": \"test\", \"title\": \"mytitle\" }";
var values1 = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonObject);
var values2 = JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonString);
This is also working
var values3 = JsonConvert.DeserializeObject<sampledata>(jsonObject);
I created JObject
JObject jObject = new JObject
{
{"name", "test" },
{"title", "mytitle" }
};
string jObjectStr = jObject.ToString();
var values = JsonConvert.DeserializeObject<sampledata>(jObjectStr);
The updated line of code:
List<sampledata> s = JsonConvert.DeserializeObject<List<sampledata>>(param);
is perfectly fine.
The problem here is that the deserializer is expecting an array when you are trying to deserialize to a list.
Try making it an array. Add this line of code to the param string:
param ="["+param+"]";//make it an array before deserialization
Complete code:
public class sampledata
{
[JsonProperty("name")]
public string name { get; set; }
[JsonProperty("title")]
public string title { get; set; }
}
public void SampleEvent(string param)
{
param ="["+param+"]";//make it an array before deserialization
List<sampledata> s = JsonConvert.DeserializeObject<List<sampledata>>(param);
}

json save object to list

Can anyone tell me how to fix this?
class Movie
{
public string Name { get; set; }
public int Year { get; set; }
}
class Program
{
static void Main(string[] args)
{
List<Movie> _data = new List<Movie>();
_data.Add(JsonConvert.DeserializeObject<Movie>(File.ReadAllText(#"mov.txt")));
Console.ReadKey();
}}
[{"Name" : "John","Year" : "1990"},
{"Name" : "Mark","Year" : "2005"}]
Theres Exception:
Additional information: Cannot deserialize the current JSON array
(e.g. [1,2,3]) into type 'testjson.Movie' because the type requires a
JSON object (e.g. {"name":"value"}) to deserialize correctly.
Thank you.
It's a JSON array, so you need to deserialize as such:
JsonConvert.DeserializeObject<Movie[]>
So you can call AddRange(), which accepts an IEnumerable<Movie>:
_data.AddRange(JsonConvert.DeserializeObject<Movie[]>(File.ReadAllText(#"mov.txt")));
But in this case you can deserialize the list itself:
List<Movie> _data;
_data = JsonConvert.DeserializeObject<List<Movie>>(File.ReadAllText(#"mov.txt")));
try this (thanks to CodeCaster):
_data.AddRange(JsonConvert.DeserializeObject<List<Movie>>(File.ReadAllText(#"mov.txt")));
because this
[
{ ... },
{ ... },
...
]
in your json means that it is an array. So you have to deserialize it as an array.

Categories