I am trying to make a json file with all the bonus characteristic you get per level.
Json is like this :
{
"0": {
"Armor": 1,
"Strenght": 1,
"Mana": 2,
"Power": 1,
"Health": 1
},
"1": {
"Armor": 1,
"Strenght": 1
}
}
I then call a loader :
struct LevelBonus
{
int Power;
int Mana;
int Strenght;
int Armor;
int Health;
}
Dictionary<string, LevelBonus> statsPerLevel;
statsPerLevel = FileLoaderManager.instance.LoadJSONData<Dictionary<string, LevelBonus>>("PlayerStats/level.json");
And somewhere else there is
public T LoadJSONData<T>(string path)
{
string filePath = Path.Combine(Application.streamingAssetsPath, path);
if (File.Exists(filePath))
{
string dataAsJson = File.ReadAllText(filePath);
T loadedData = JsonUtility.FromJson<T>(dataAsJson);
return loadedData;
}
else
{
Debug.LogError("Cannot load game data!");
return default(T);
}
}
My Data is loaded, but not parsed correctly. Basically, no error, but no data returned event tho the file is read and until
T loadedData = JsonUtility.FromJson<T>(dataAsJson);
I can read the data correctly as string. but that FromJson return nothing
What I am missing ?
EDIT : https://answers.unity.com/questions/1583163/importing-data-from-json.html?childToView=1583169#comment-1583169
What I pretty much always do when loading Jsons is never ever write them by hand. I create an instance of of what I'll want to write in memory first, than SAVE to json - to make sure the field layout is exactly as expected by the serialiser - its easy to write a json that is valid, but makes no sens when mapped to a C# class
In your case the answer is simple. in Json structure you have
{ field_name : field_value }
pairs. But when it says "1":value, it won't ever deserialize, becuase the name of the field is "1", which is not a valid field name in C# (it has to start with a letter). The definition object to which you desrialize would have to look like
class MyStats
{
public int Armor;
public int Strenght;
public int Mana;
public int Power;
public int Health;
}
I imagine this is rougly right, however to deserialize your example, your container object would need to be defined like this (which is invalid)
class MyContainerObject
{
public MyStats 1; // ERROR: INVALID FIELD NAME !!
public MyStats 2; // ERROR: INVALID FIELD NAME !!
}
It is not returning an error as the Json is valid, and the parser just skips fields that don't match the class definition you are using.
Regading the use of arrays you can either hack a wrapper extension (as suggested by Dharmashree) which is a bit quirky (JsonUtility needs to know the concrete class to which it is deserialising and it can't go directly to array or list so for example:
[
{"a": 1 },
{"b": 1 },
{"c": 1 }
]
while being a valid json, it will not be parsed by JsonUtility (raw, anonymous array), however this will
{
"MyStats": [
{ "a": 1 },
{ "b": 2 },
{ "c": 1 }
]
}
you can structure your data to contain the array within a container object, so your main object could be defined as:
class MyContainerObject
{
public MyStats[] stats;
}
Access to your elements is then via myList[index]
Anwyays, I will again highliy recommending starting with WRITING a json representing your structure, checking if that deserialising works as expected, and only then edit the file by hand.
Try to use array of Json. You can follow this sample here.
https://www.newtonsoft.com/json/help/html/ToObjectComplex.htm
Not able to comment so mentioning in answer.
The Person class used in NewtonSoft Documentation should have following structure.
public class Person
{
public string Name {get;set;}
}
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 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.
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 am consuming a web service that will calculate tax. The problem is I don't always get the data back in exactly the same formatn (see example below). When I deserialize the data my code throws an exception. Any tips on what I can do to allow the deserialization to handle a single element or an array of a single element? FYI, I get back a lot more data in addition to the tax, but I am only showing the tax part to keep it simple.
Sometimes I get the data like this:
{
"data": {
"tax": [{
"amount": 0.00,
"category": 0.0
}]
}
}
Sometimes I get it like this:
{
"data": {
"tax": {
"amount": 336.01,
"category": 0.0
}
}
}
Here is my class:
public class Tax
{
public float amount { get; set; }
public float category{ get; set; }
}
I am thinking about adding an [XmlIgnore] attribute and manually deserailizing to get the tax data, but I would like to stay away from that if possible.
Not sure how XmlIgnore would help with your JSON serialization, but i would suggest using Newtonsoft.Json to deserialize your payload to JObject. Then you can use Linq to JSON to investigate the result and perhaps manually instantiate your own object based on the type of "tax" property (JArray or JObject)
see LINQ to JSON for more info.
Make two (or more) different classes, then use the one that doesn't throw an exception when you deseralize.
It looks like you could deseralize the array data using this class:
public class data
{
public Dictionary<string, double> tax { get; set; }
}
If that class successfully deserializes, you can then copy it over to the tax class, either manually, or by using Reflection.
I'd use JSON.Net (link to nuget). Then I'd get a JObject from JObject.Parse method and check whether the relevant child element is JObject or JArray. Then, I'd convert it to your data class (or a dynamic type)
dynamic taxData;
var json = JObject.Parse(response);
var rawTaxData = json["data"]["tax"];
if (rawTaxData is JObject)
{
taxData = JsonConvert.DeserializeObject(rawTaxData);
}
else if (rawTaxData is JArray)
{
var actualData = rawTaxData [0];
taxData = JsonConvert.DeserializeObject(actualData);
}
Also, just to be sure that your server actually returned data and not, for example, error message, use TryGetValue:
JToken dataToken;
if (!json.TryGetValue("data", out dataToken))
{
var rawTaxData = dataToken["tax"];
// ...
}
I have a JSON string like following string
{
FlightId : 1,
[
{
AirplaneId : 1
},
{
AirplaneId : 2
}
]
}
I have defined 2 classes to convert this JSON string to the objects of these 2 classes :
class Airplane
{
int AirplaneId;
}
class Flight
{
int FlightId;
List<Airplane> Airplanes;
}
During convert the string to these classes objects I get an error. The error tells me that JSON string is not recognized and I should define a name for the list in my JSON string. I can not change the JSON string , how to define my class to convert this JSON String
Yes, you get an error since that is not a valid JSON.
In order to make it valid, you need to have a key to match your list value:
{
"FlightId" : 1,
"Airplanes": [
{
"AirplaneId" : 1
},
{
"AirplaneId" : 2
}
]
}
Also, you need to wrap your key values in quotes.
You can use https://www.jsoneditoronline.org/ in the future to make sure your JSON strings are valid.
The problem is your array, you need to define a key for it, like:
{
"FlightId" : 1,
"Airplanes": [
{
"AirplaneId" : 1
},
{
"AirplaneId" : 2
}
]
}
Airplanes must be a list in your class later.
JSON is a "Key-Value" based format, so every value (even arrays) needs a key.