I have a JsonString:
"baseAbilities":"[{"baseId":1,"name":"Focused Elemental Strike"}]"
I want to make it:
"baseAbilities":[{"baseId":1,"name":"Focused Elemental Strike"}]
So the it is easy for JSON utility to deserialise it. Any suggestions
EDIT:
This is basically a json object in the following Json String:
{"data”: [{"id":9,"name":"Sam5","baseAbilities":"[{\"baseId\":1,\"name\":\"Focused Elemental Strike\"},{\"baseId\":9,\"name\":\"Cleanse\"}]"]}
The backend developer saved JSON in a column baseAbilities as a string. Now I don't have the access to Back end APIs. So i need to convert this string baseAbilities to JSON so that I can access objects inside it.
Now I use these classes to decode JSON:
[System.Serializable]
class GetBAResult
{
public List<bounceAbilityData> data;
}
[System.Serializable]
class bounceAbilityData
{
public int id;
public string name;
public string baseAbilities;
}
And this is how I decode JSON:
GetBAResult P = JsonUtility.FromJson<GetBAResult>(w.text);
for (int i = 0; i < P.data.Count; i++)
{
Debug.Log(P.data[i].name);
GameObject layoutGroupNameButton = (GameObject)Instantiate(prefabBAButton);
layoutGroupNameButton.transform.SetParent(ParentPanel, false);
layoutGroupNameButton.GetComponentInChildren<Text>().text = P.data[i].name;
layoutGroupNameButton.GetComponent<BounceAbilityButton>().id = P.data[i].id;
layoutGroupNameButton.GetComponent<BounceAbilityButton>().name = P.data[i].name;
Debug.Log(P.data[i].baseAbilities);
}
I need to get things inside baseAbilities such as "baseID" and "name"
Have you tried this?
JObject json = JObject.Parse(str);
documentation
With a class set of
[System.Serializable]
class GetBAResult
{
public List<bounceAbilityData> data;
}
[System.Serializable]
class bounceAbilityData
{
public int id;
public string name;
public List<BaseAbilities> baseAbilities;
}
[System.Serializable]
class BaseAbilities
{
public int baseId;
public string name;
}
You can then use the following to Deserialize your JSON to an instance of GetBAResult
string json = "{\"data\":[{\"id\":9,\"name\":\"Sam5\",\"baseAbilities\":[{\"baseId\":1,\"name\":\"Focused Elemental Strike\"},{\"baseId\":9,\"name\":\"Cleanse\"}]}]}";
GetBAResult myObject = JsonUtility.FromJson<GetBAResult>(json);
BaseAbilities abilities = myObject.data[0].baseAbilities[0];
You can read more about JSON Deserialization here on the Unity Documentation
https://docs.unity3d.com/Manual/JSONSerialization.html
The original questions says that you want to change:
"baseAbilities":"[{"baseId":1,"name":"Focused Elemental Strike"}]"
to
"baseAbilities":[{"baseId":1,"name":"Focused Elemental Strike"}]
Basically, you want to remove the " before the [{" then remove the final " at the end of the json string. The problem is that even after you do this, "baseAbilities":[{"baseId":1,"name":"Focused Elemental Strike"}] cannot be serialized to json.
You need to add { in front of it and } at the end of it.
The final string after adding { in front of it and } at the end is:
{"baseAbilities":[{"baseId":1,"name":"Focused Elemental Strike"}]}
The fixJson function below fixes those problems and this is how to use it:
[System.Serializable]
public class BaseAbility
{
public int id;
public string name;
}
[System.Serializable]
public class GetBAResult
{
public List<BaseAbility> baseAbilities;
}
void Start()
{
// StartCoroutine(RespawnPlayer());
string fixedJson = fixJson(w.text);
//string fixedJson = fixJson("\"baseAbilities\":\"[{\"id\":1,\"name\":\"Focused Elemental Strike\"}]\"");
Debug.Log("Fixed Json: " + fixedJson);
GetBAResult P = JsonUtility.FromJson<GetBAResult>(fixedJson);
Debug.Log("Count Json: " + P.baseAbilities.Count);
for (int i = 0; i < P.baseAbilities.Count; i++)
{
Debug.Log("Name: " + P.baseAbilities[i].name);
Debug.Log("Base ID: " + P.baseAbilities[i].id);
}
}
string fixJson(string jsonToFix)
{
//First srting with `"` that will be removed
const string firstString = "\"baseAbilities\":\"";
//Last string with `"` that will be removed
const string lastString = "\"";
//String that will be used to fix the "baseAbilities":"[ with the `"`
const string fixedFirstString = "\"baseAbilities\":";
//Get the first Index of firstString
int firstIndex = jsonToFix.IndexOf(firstString);
//Remove First Index of `firstString`
jsonToFix = jsonToFix.Remove(firstIndex, firstString.Length);
int lastIndex = jsonToFix.LastIndexOf(lastString);
//Remove everything from Last `lastString` to the end
jsonToFix = jsonToFix.Remove(lastIndex);
//Append the correct/fixed string without `"` to the beginning of the json data
jsonToFix = fixedFirstString + jsonToFix;
//Add `{` to the begging and `}` to the end of the json data
jsonToFix = "{" + jsonToFix + "}";
return jsonToFix;
}
Let's say you have a class like this:
using System;
using System.Collections.Generic;
using UnityEngine;
public class JsonTest : MonoBehaviour
{
[Serializable]
public class Ability
{
public int baseId;
public string name;
public Ability(int _baseId, string _name)
{
baseId = _baseId;
name = _name;
}
}
public class Abilities
{
public List<Ability> baseAbilities;
public Abilities(List<Ability> _baseAbilities)
{
baseAbilities = _baseAbilities;
}
}
void Start()
{
List<Ability> list = new List<Ability>();
list.Add(new Ability(1, "Focused Elemental Strike"));
list.Add(new Ability(2, "Another ability"));
Abilities baseAbilities = new Abilities(list);
string serializedAbilites = JsonUtility.ToJson(baseAbilities);
Debug.Log(serializedAbilites);
Abilities deserializedAbilites = JsonUtility.FromJson<Abilities>(serializedAbilites);
}
}
You have an Ability class marked as Serializable containing and id and a name.
You have another class Abilities used as a wrapper for a list of abilities.
You can then serialize a list of abilities using JsonUtility.ToJson(). Which will give you the following string:
{
"baseAbilities": [
{
"baseId": 1,
"name": "Focused Elemental Strike"
},
{
"baseId": 2,
"name": "Another ability"
}
]
}
And of course you can deserialize it using JsonUtility.FromJson().
Is this what your looking for ?
Related
"title" : { "newTitle" : "Test"}
"tags" : { "newTags" : ["Tag1", "Tag2"] }
Newtonsoft.Json.Linq;
var json = JObject.Parse(json: json);
var title; // "Test2" in title
List<string> tags; // "TagA", "TagB", "TagC" in tags
json["title"]["newTitle"] = title; // works well
json["tags"]["newTags"] = tags; // not work
I want the JSON result as below:
"title" : { "newTitle" : "Test2"}
"tags" : { "newTags" : ["TagA", "TagB", "TagC"] }
I want to modify some values of JSON. int or string worked well. However, the List or Array does not work.
Please give me a good opinion.
I used a translator. So the writing may be awkward.
Assume your JSON data has defined object template, you can create a class based on your JSON data. With Newtonsoft.Json, you deserialize your JSON into an object and next update the object's properties value.
Note: When access object's inner properties for example Title.NewTitle and Tags.NewTags, you may need to add some null checking for preventing NullReferenceException.
1st solution: Convert to strongly-typed object
public static void Main()
{
var json = "{\"title\" : { \"newTitle\" : \"Test\"}, \"tags\" : { \"newTags\" : [\"Tag1\", \"Tag2\"] }}";
var inputObj = JsonConvert.DeserializeObject<JsonInput>(json);
inputObj.Title.NewTitle = "Test2";
inputObj.Tags.NewTags = new List<string> {"TagA", "TagB", "TagC"};
Console.WriteLine(JsonConvert.SerializeObject(inputObj));
}
public class JsonInput
{
public Title Title {get;set;}
public Tags Tags {get;set;}
}
public class Title
{
public string NewTitle {get;set;}
}
public class Tags
{
public List<string> NewTags {get;set;}
}
1st solution Code snippets and Output
2nd solution: With dynamic
To update array, you need parse your List<string> to JArray type
public static void Main()
{
var json = "{\"title\" : { \"newTitle\" : \"Test\"}, \"tags\" : { \"newTags\" : [\"Tag1\", \"Tag2\"] }}";
var title = "Test2"; // "Test2" in title
List<string> tags = new List<string> {"TagA", "TagB", "TagC"}; // "TagA", "TagB", "TagC" in tags
dynamic root = JObject.Parse(json);
JObject titleObj = (JObject)root["title"];
titleObj["newTitle"] = title;
JObject tagsObj = (JObject)root["tags"];
tagsObj["newTags"] = JArray.FromObject(tags);
Console.WriteLine(root);
}
2nd solution Code snippets and Output
try this
var jsonObject=JObject.Parse(json);
var newTitle = "Test2";
List<string> newTags = new List<string> { "TagA", "TagB", "TagC"};
jsonObject["title"]["newTitle"]= newTitle;
jsonObject["tags"]["newTags"]= JArray.FromObject(newTags);
result
{
"title": {
"newTitle": "Test2"
},
"tags": {
"newTags": [
"TagA",
"TagB",
"TagC"
]
}
}
I am trying to read from a JSON file a series of items into an Object array.
Unfortunately it comes back as null.
Very similar to this issue Unity C# JsonUtility is not serializing a list
So in my particular situation I have the class for the item:
[Serializable]
public class StateData
{
public string name;
public string location;
public string gameText;
}
The class of the collection of items:
[Serializable]
public class StateDataCollection
{
public List<StateData> stateDatas = new List<StateData>();
}
And the class where this is invoked:
public class JSONReader : MonoBehaviour
{
private const string Path = #"S:\repos\myProject\Assets\gameText\";
void Start()
{
string json = File.ReadAllText(Path + "StateData.json");
StateDataCollection stateDataCollection = new StateDataCollection();
stateDataCollection = JsonUtility.FromJson<StateDataCollection>(json);
}
}
Finally the json
{
"StateData":[
{
"name": "name",
"location":"location",
"gameText" : "gameText"},
{
"name": "name",
"location":"location",
"gameText" : "gameText"},
{
"name": "name",
"location":"location",
"gameText" : "gameText"
}]
}
The object comes back as null.
The file is reading OK.
Any ideas where this is failing?
TY!
I would start by checking a few things first:
Check if the file actually exists. Just use a small Debug.Log(File.Exists(path)).
Try another path -> something save like: Application.persistentDataPath. On Windows this will give you something like: %userprofile%\AppData\Local\Packages<productname>\LocalState. This ensures you being able to read/write from/to files.
Fill the List with actual data so you can differentiate between a saved list and the default list.
Edit 1:
I just replicated your Code and made some adjustments to it. It's not perfect but it definately worked for me.
StateData:
using System;
[Serializable]
public struct StateData
{
public string m_Name;
public string m_Location;
public string m_GameText;
public StateData(string name, string location, string gameText)
{
m_Name = name;
m_Location = location;
m_GameText = gameText;
}
}
StateDataCollection:
using System;
using System.Collections.Generic;
[Serializable]
public class StateDataCollection
{
public List<StateData> m_StateData;
public StateDataCollection() => m_StateData = new List<StateData>();
}
JSONReader:
using System.IO;
using UnityEngine;
public class JSONReader : MonoBehaviour
{
private const string FILENAME = "StateData.json";
private string m_path;
public string FilePath {
get => m_path;
set => m_path = value;
}
void Start()
{
FilePath = Path.Combine(Application.persistentDataPath, FILENAME);
Debug.Log(FilePath);// delete me
StateDataCollection stateDataCollection = new StateDataCollection();
stateDataCollection.m_StateData.Add(new StateData("Peter", "X", "123"));
stateDataCollection.m_StateData.Add(new StateData("Annie", "Y", "42"));
stateDataCollection.m_StateData.Add(new StateData("TheGuyFromTheSupermarket", "Supermarket", "666"));
SaveStateDataCollectionToPath(FilePath, stateDataCollection);
LoadStateDataCollectionFromPath(FilePath);
}
private void SaveStateDataCollectionToPath(string path, StateDataCollection stateDataCollection)
{
// ToDo: some checks on path and stateDataCollection
string json = JsonUtility.ToJson(stateDataCollection, true);// prettyPrint active
File.WriteAllText(path, json);
}
private void LoadStateDataCollectionFromPath(string path)
{
if(File.Exists(path)) {
Debug.Log($"File exists at: {path}");// delete me
string json = File.ReadAllText(path);
StateDataCollection stateDataCollection = JsonUtility.FromJson<StateDataCollection>(json);
// delete me
Debug.Log($"StateDataCollection count: { stateDataCollection.m_StateData.Count}");
int i = 1;
stateDataCollection.m_StateData.ForEach(o => {
Debug.Log(
$"Item Nr.: {i}\n" +
$"Name: {o.m_Name}\n" +
$"Location: {o.m_Location}\n" +
$"GameText: {o.m_GameText}\n\n");
++i;
});
}
}
}
I also added a few Debug.Log()s for testing.
Usage:
Run it once with SaveStateDataCollectionToPath(FilePath, stateDataCollection); active and once without it. The Console should display 3 items.
Edit 2:
I think your issue might have been naming-convention violation. File requires using System.IO;, which beside File also contains Path. Unfortunately you also named your const string "Path".
I am trying to get some currency values from an api. it's returning the data in the following format:
{"PKR_PKR":{"val":1}}
I want to show this value in textbox but there's an error
"Object reference not set to an instance of object".
I've tried the following code:
try
{
string endPoint = #"http:urlhere";
string ResultJson = "";
using (WebClient wc = new WebClient())
{
ResultJson = wc.DownloadString(endPoint);
}
JsonData values = JsonConvert.DeserializeObject<JsonData>(ResultJson);
txtBalanceRate.Text = values.CurrencyValue.ToString();
}
catch (Exception ex) { }
Class code:
class JsonData
{
public object CurrencyValue { get; set; }
}
**
UPDATE
**
Note: I can not update PKR_PKR Class becuase every time the name of variable is different for different currencies i.e. it can be USD_PKR , EUR_PKR etc
How can I resolve this?
FOLLOWING IS THE UPDATED CODE:
try
{
string endPoint = #"http://free.currencyconverterapi.com/api/v5/convert?q="+ddlCurrency.SelectedValue.ToString()+"_PKR&compact=y";
string ResultJson = "";
using (WebClient wc = new WebClient())
{
ResultJson = wc.DownloadString(endPoint);
}
RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(ResultJson);
txtBalanceRate.Text = rootObject.PKR_PKR.val.ToString();
}
catch (Exception ex)
{
}
public class PKRPKR
{
public int val { get; set; }
}
public class RootObject
{
public PKRPKR PKR_PKR { get; set; }
}
If you are going to have dynamic object then you should try this out
dynamic data = Newtonsoft.Json.JsonConvert.DeserializeObject(json);
Type typeOfDynamic = data.GetType();
if( typeOfDynamic.GetProperties().Where(p => p.Name.Equals("PKR_PKR")).Any())
{
console.WriteLine(data.PKR_PKR.val);
}
else if( typeOfDynamic.GetProperties().Where(p => p.Name.Equals("USD_PKR")).Any())
{
console.WriteLine(data.USD_PKR.val);
}
else if( typeOfDynamic.GetProperties().Where(p => p.Name.Equals("EUR_PKR")).Any())
{
console.WriteLine(data.EUR_PKR.val);
}
above way is not tried and tested but you can have try like this as you json is dynamic.
Above way is checking property exist or not and get val from dynamci object
Your class structure is incorrect can you please try below class structure
public class PKRPKR
{
public int val { get; set; }
}
public class RootObject
{
public PKRPKR PKR_PKR { get; set; }
}
RootObject rootObject = JsonConvert.DeserializeObject<RootObject>(json);
Console.WriteLine(rootObject.PKR_PKR.val);
Mostly if you see above class structure , you josn each node is represent as class, but I dont go in much detail as Visual studio can do it for me.
When comes to json to object conversion ,I make use of utility provided by Visual studio. which does conversion of json string to proper class structure. here is image of it
Read how to do it full here :
Visual Studio Generate Class From JSON or XML
If you dont have visual studio with this feature you can use this online utility : json2csharp
Note: I can not update PKR_PKR Class becuase evert time the name of
variable is different for different currencies i.e. it can be USD_PKR
, EUR_PKR etc How can I resolve this?
SOLUTION
if json string {"PKR_PKR":{"val":1}} is fixed in your case, you can use following solution for any currency name you got.
static void Main(string[] args)
{
string json1 = "{ \"PKR_PKR\":{ \"val\":1}}";
string json2 = "{ \"USD_PKR\":{ \"val\":2}}";
string json3 = "{ \"EUR_PKR\":{ \"val\":3}}";
JToken token1 = (JToken)JsonConvert.DeserializeObject(json1);
Console.WriteLine(token1.First().First()["val"]);
JToken token2 = (JToken)JsonConvert.DeserializeObject(json2);
Console.WriteLine(token2.First().First()["val"]);
JToken token3 = (JToken)JsonConvert.DeserializeObject(json3);
Console.WriteLine(token3.First().First()["val"]);
Console.ReadLine();
}
I think your receiving object should contain a dictionary, not a single string:
Check this
Or you have to improve your object structure implementing a root item which contains a PKR_PKR sub object
This question already has answers here:
Serialize and Deserialize Json and Json Array in Unity
(9 answers)
Closed 5 years ago.
I have some problems with converting a json string into a c# List!
This is my JSON that i get from form a server.
[
{"roundid":1,"coins":700,"created":"2016-03-16 11:13:26","duration":198,"score":765230},
{"roundid":3,"coins":330,"created":"2016-03-16 11:13:56","duration":123,"score":425726},
{"roundid":4,"coins":657,"created":"2016-03-16 11:21:23","duration":432,"score":75384},
{"roundid":8,"coins":980,"created":"2016-03-16 11:23:19","duration":271,"score":827200}
]
In my C# program i then try to transform my json string into useable objects using with this function
public List<Round> getPlayerRounds(string username)
{
string url = BaseURL + "op=findUserRounds&username=" + username;
var json = new WebClient().DownloadString(url);
RoundDataList rounds = JsonUtility.FromJson<RoundDataList>(json);
List<Round> playerRounds = new List<Round>();
//for (var i = 0; i < rounds.roundList.Count; i++)
for (var i = 0; i < rounds.roundList.Length; i++)
{
RoundData rd = rounds.roundList[i];
Round r = rd.getRound();
playerRounds.Add(r);
}
return playerRounds;
}
Here i get error
ArgumentException: JSON must represent an object type.
I've looked around and haven't found anything that works, Tried 2-3 solution even tried edited my php webservice that creates the JSON string.
My Classes looks like this
/* This is previus atempt to solve the issue
[Serializable]
public class RoundDataList
{
public List<RoundData> roundList;
}
*/
[Serializable]
public class RoundDataList
{
public RoundData[] roundList;
}
[Serializable]
public class RoundData
{
public int roundid;
public int coins;
public DateTime created;
public int duration;
public int score;
public Round getRound()
{
Round r = new Round();
r.Roundid = roundid;
r.Coins = coins;
r.Created = created;
r.Duration = duration;
r.Score = score;
return r;
}
}
Thank for looking at this long post!
Unity's new Json API does not support Json array and that is exactly what your problem is. There is a way to do it but it is a long process to repost again. Just read how to do it here.What you are looking for is the second solution that says "2. MULTIPLE DATA(ARRAY JSON)."
Creating a class and another class holding list of it works for me.
[Serializable]
public class Questions
{
public string id;
public string question;
public string answer1;
public string answer2;
}
[Serializable]
public class QuestionList
{
public List<Questions> list;
}
//and
var jstring = "{\"list\":[{\"id\":\"1\",\"question\":\"lorem Ipsome \",\"answer1\":\"yes\",\"answer2\":\"no\"},{\"id\":\"2\",\"question\":\"lorem Ipsome Sit dore iman\",\"answer1\":\"si\",\"answer2\":\"ne\"}]}";
var result = JsonUtility.FromJson<QuestionList>(jstring);
From a list, Convert to JSON
List<Questions> questionlist = new List<Questions>();
questionlist.Add(new Questions()
{
answer1 = "yes",
answer2 = "no",
id = "1",
question = "lorem Ipsome "
});
questionlist.Add(new Questions()
{
answer1 = "si",
answer2 = "ne",
id = "2",
question = "lorem Ipsome Sit dore iman"
});
var ql = new QuestionList();
ql.list = questionlist;
var result = JsonUtility.ToJson(ql);
//this gives
{"list":[{"id":"1","question":"lorem Ipsome ","answer1":"yes","answer2":"no"},{"id":"2","question":"lorem Ipsome Sit dore iman","answer1":"si","answer2":"ne"}]}
Note: "list" and questionList.list should be in same name.
I am trying to use one web service which returns demanded data in json format. Now the actual point is I can fetch the data from the particular web service url in string.
string url= #"http://api.oodle.com/api/v2/listings?key=TEST®ion=chicago&category=vehicle&format=json";
string jsonString = new WebClient().DownloadString(url);
Now the point is I get the data in string (in JSON format). But I dont know how to convert the string into JSON string and how to fetch data from this string.
Let me give you example so you can easily understand
if my jsonString is like
{
"current":{
"region":{
"id":"chicago",
"name":"Chicago"
},
"category":{
"id":"vehicle",
"name":"Cars & Vehicles",
"abbrev":"Vehicles"
},
"start":1,
"num":10
}
}
How can i get region_name from that string ? Hope you understand me ! Try to use Test Link !
Add a reference to System.Web and then add to your using section
using System.Web.Script.Serialization;
Then (using your example json string)
string jsonString = "{\"current\":{\"region\":{\"id\":\"chicago\",\"name\":\"Chicago\"},\"category\":{\"id\":\"vehicle\",\"name\":\"Cars & Vehicles\",\"abbrev\":\"Vehicles\"},\"start\":1, \"num\":10}}";
JavaScriptSerializer serializer = new JavaScriptSerializer();
CurrentRecord currentRecord = serializer.Deserialize<CurrentRecord>(jsonString);
string regionName = currentRecord.current.region.name;
Also add the following classes to your project:
[Serializable]
public class CurrentRecord
{
public current current;
}
[Serializable]
public class current
{
public region region;
public category category;
public int start;
public int num;
}
[Serializable]
public class region
{
public string id;
public string name;
}
[Serializable]
public class category
{
public string id;
public string name;
public string abbrev;
}
Are you processing the JSON return string in Java, or JavaScript?
If you are processing the JSON response string in Java, you may make use of GSON. Here is a tutorial showing you how: Parsing a JSON String into an object with GSON easily.
For your case, you need a class like:
class Current{
private Region region;
private Category category;
private int start;
private int num;
// getters and setters
class Region{
private String id;
private String name;
// getters and setters
}
class Category{
private String id;
private String name;
private String abbreviation;
// getters and setters
}
}
Else if you are processing this JSON response String in Javascript, then you can have a look at this: http://www.json.org/js.html
alert(jsonReturnString.current.region.name);