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.
Related
I have json and an array inside it what looks like:
{
"data" : [
[int],
[...],
[..n]
]
}
Can I get array from "data" using JsonUtility? Or any other way?
For now, I can get "data" using following code:
[System.Serializable]
public class ObjectProperties
{
public int[] data;
public string color;
}
public void LoadFromJson()
{
objectProperties = JsonUtility.FromJson<ObjectProperties>(File.ReadAllText(Application.streamingAssetsPath + "/CubeSettings.json"));
}
And I can get any data but array I need.
In case the structure actually is e.g.
{
"data" : [
[1],
[2],
[3]
]
}
This is a nested array int[][] (an array where each element is an array itself).
So either the JSON should rather look like
{
"data" : [
1,
2,
3
]
}
or - if changing the JSON is not an option for you - your c# structure rather has to be
[System.Serializable]
public class ObjectProperties
{
public int[][] data;
public string color;
}
BUT such nested arrays are not supported by the built-in JsonUtility (see Script Serialization).
For this you would need to use a different library like e.g. Newtonsoft .NET JSON (available as a Package via the Package Manager)
var json = File.ReadAllText(Application.streamingAssetsPath + "/CubeSettings.json"));
var objectProperties = JsonConvert.DeserializeObject<ObjectProperties>(json);
This also means the field will not be visible/editable in the Inspector and will not be saved together with the scene or prefabs in Unity.
I assume 'data' is array itself, but not array of array.
So it should be
{"data":[1,2,3],"color":"red"}
Also you should define get/set to include fields into serialization:
[System.Serializable]
public class ObjectProperties
{
public int[] data { get; set; }
public string color { get; set; }
}
Now you can run it:
var objectProperties = JsonSerializer.Deserialize<ObjectProperties>(...);
I have a JSON string in below format for which I want to deserialize it into C# List. But the record number "1","2","3" (it can be upto 1,2,3...n depends on the json response each time) in JSON restricting me to deserialize it into C# object using Newtonsoft.Json
{
"1":{
"UID":"1",
"LICENCENO":"licenseno",
"NAME":"ABC"
},
"2":{
"UID":"2",
"LICENCENO":"licenseno",
"NAME":"PQR"
},
"3":{
"UID":"3",
"LICENCENO":"licenseno",
"NAME":"XYZ"
}
}
I am using below code for deserialization
var result = Newtonsoft.Json.JsonConvert.DeserializeObject<List<DriverMaster>>(json);
I have DriverMaster class created as-
public class DriverMaster
{
public string UID { get; set; }
public string LICENCENO { get; set; }
public string NAME { get; set; }
}
Deserialization line giving unhandled exception, I know I am doing it in wrong way, because DriverMaster json object cannot be extracted into c# directly without doing something to record number 1,2,3...n in c#. Can anyone please help me to sort it out? Thanks in advance.
You were close:
var result = JsonConvert.DeserializeObject<Dictionary<string, DriverMaster>>(json)
.Select(x => x.Value)
.ToList();
Solution.
Change your code to use...
var result = JsonConvert.DeserializeObject<Dictionary<int, DriverMaster>>(json);
Explaination
The type is not the same... The List<DriverMaster>type will convert to JSON like so...
{
"1":
{
"DriverMaster": {
"UID":"1",
"LICENCENO":"licenseno",
"NAME":"ABC"
}
}
}
This doesn't match what you showed in your question...
The type that you are looking for is actually Dictionary<int, DriverMaster>, which is a key/value pair which will output a JSON string like so
{
"1": { ... },
"2": { ... },
"3": { ... }
}
In order to fix that, you need to use the Dictionary<int, DriverMaster> type instead.
For these types of things I like to use the often overlooked feature of JToken.SelectTokens. This function allows you to select tokens within a json string and permits the use of wildcards.
Here's some code that will deserialize your sample by selecting past the 1,2,3...N in the json:
public static IEnumerable<DriverMaster> Deserialize(string json)
{
return JToken.Parse(json).SelectTokens("*")
.Select(jToken => jToken.ToObject<DriverMaster>());
}
The * basically says to select all tokens after the root, so it's selecting the values associated with 1, 2, 3.. etc... Here's another SO answer that shows a more complicated usage of the SelectTokens method.
You need to use
public class DriverMaster
{
public string UID { get; set; }
public string LICENCENO { get; set; }
public string NAME { get; set; }
}
public class Root
{
[JsonExtensionData]
public IDictionary<string,JToken> Data {get;set;}
}
and
var result = Newtonsoft.Json.JsonConvert.DeserializeObject<Root>(json);
If you want to have result as List, you can parse the result as.
var list = new List<DriverMaster>();
foreach(KeyValuePair<string, JToken> token in result.Data)
{
list.Add(token.Value.ToObject<DriverMaster>());
}
That would give you the desired result as
1 licenseno ABC
2 licenseno PQR
3 licenseno XYZ
I am stuck while returning api result, I have a class like
public partial class Sample
{
[JsonProperty("classificator")]
public List<Classificator> Classificator { get; set; }
}
public partial class Classificator
{
[JsonProperty("Value")]
public string Value { get; set; }
[JsonProperty("Description")]
public string Description { get; set; }
}
Let's say GetJson method retrieve our data from the database, there are 2 records and the data like
-- Value - Description
1- A - AXA
2- B - BXA
response = GetJson(); // this method gets data from db
return Content(HttpStatusCode.OK, response);
when I return this, it's like
{
"classificator": [{
"Value": "A",
"Description": "AXA"
}, {
"Value": "B",
"Description": "BXA"
}
]
}
but I would like to see like, I want to see bellowing result;
{
"classificator": [{
"A": "AXA"
}, {
"B" : "BXA"
}
]
}
I would like to ask you maybe someone knows a good practice or document(tutorial) about it.
I solve it by using, Dictionary < string, model >
but I need to return a huge nested field I cant implement this solution for all different nodes.
I solved by using Dictionary< string, object >
I put 2 nested objects inside of an object value. In my case it looked some complex I refactor and try to work through readable dictionary hierarchy.
basically for this example it something like below,
Dictionary<string, object> fooDict = new Dictionary<string, object>();
fooDict.Add("A", "AXA"); // in my case I put 2 nested object to value field
fooDict.Add("B", "BXA");
var serializedObject = JsonConvert.SerializeObject(fooDict);
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\xxx\result.txt", true))
{
file.WriteLine(serializedObject);
}
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.
I'd like to convert a List<some_object> to JSON.
public class some_object
{
public string field1 {get; set;}
public string field2 {get; set;}
}
I want to serialize this:
var somejson = new {
some_objects = new List<some_object>() {...some items...};
}
Standard serialization produces an array:
{
"some_objects": [
{
"field1":"value1",
"field2":"value2"
},
{
"field1":"value3",
"field2":"value4"
}
]
}
Instead, I want to produce something like this (more XML-like):
{
"some_objects":
{
"some_object": {"field1":"value1", "field2":"value2"},
"some_object": {"field1":"value3", "field2":"value4"}
}
}
Is there any way of producing this result?
No, JSON object properties need to be unique
All of the properties of your objects need to be different. Conceptually, XML represents an object, but the tags don't directly link to the concept of a property. The JSON way to do this would be what you posted:
{
"some_objects": [
{"field1":"value1", "field2":"value2"},
{"field1":"value3", "field2":"value4"}
]
}
Alternatively, use a dictionary giving items unique names
If you want to give each item a name that can then be used to access them, you can use a dictionary:
var dict = new {
some_objects = new Dictionary<string,some_object>(){
{ "a" , new some_object { field1="value1",field2="value2" } },
{ "b" , new some_object { field1="value3",field2="value4" } },
}
}
This would serialize into:
{
"some_objects":
{
"a": {"field1":"value1", "field2":"value2"},
"b": {"field1":"value3", "field2":"value4"}
}
}
no, because you will get objects with the same name, called: some_object
think... if you could do it, how you will refer to one of them, using some_objects.some_object how do you know which is?
It seems like you want to store some kind of metadata, specifically the type of object, where with XML you could use an attribute. You would have to do something like add a separate property:
public class some_object
{
public string typeText { get { return GetType().ToString(); } }
public string field1 { get; set; }
public string field2 { get; set; }
}
Which would theoretically generate JSON that looks something like:
{
"some_objects": [
{
"typeText":"MyNamespace.some_object",
"field1":"value1",
"field2":"value2"
},
{
"typeText":"MyNamespace.some_object",
"field1":"value3",
"field2":"value4"
}
]
}
Depending on your needs, you might want to encapsulate this metadata into its own class.