在Unity中对Json和Json数组进行序列化和反序列化
我有一个从PHP文件发送到使用WWW
统一的项目列表。 WWW.text
看起来像[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]
在那里我从string修剪额外的[]
。 当我尝试使用Boomlagoon.JSON
parsing它时,只有第一个对象被检索。 我发现我必须deserialize()
列表并导入MiniJSON。
但我很困惑如何反序列化()这个列表。 我想遍历每个JSON对象并检索数据。 我如何使用C#在Unity中做到这一点?
我正在使用的类是
public class player { public string playerId { get; set; } public string playerLoc { get; set; } public string playerNick { get; set; } }
修剪完[]
我能够使用MiniJSONparsingJSON。 但它只返回第一个KeyValuePair
。
IDictionary<string,object> s = Json.Deserialize(serviceData) as IDictionary<string,object>; foreach (KeyValuePair<string, object> kvp in s) { Debug.Log(string.Format("Key = {0}, Value = {1}", kvp.Key, kvp.Value)); }
谢谢!
在5.3.3更新之后,Unity将JsonUtility添加到它们的API中。 忘记所有的第三方库,除非你正在做一些更复杂的事情。 JsonUtility比其他Json库快。 更新到Unity 5.3.3或更高版本,然后尝试下面的解决scheme。
JsonUtility
是一个轻量级的API。 只支持简单的types。 它不支持Dictionary等集合。 List
是一个例外。 它支持List
和List
数组!
如果你需要序列化一个Dictionary
或者做一些简单的序列化和反序列化简单的数据types,使用第三方API。 否则,继续阅读。
要序列化的示例类:
[Serializable] public class Player { public string playerId; public string playerLoc; public string playerNick; }
1.一个数据对象(非arraysJSON)
序列化A部分 :
使用public static string ToJson(object obj);
Json public static string ToJson(object obj);
方法。
Player playerInstance = new Player(); playerInstance.playerId = "8484239823"; playerInstance.playerLoc = "Powai"; playerInstance.playerNick = "Random Nick"; //Convert to Jason string playerToJason = JsonUtility.ToJson(playerInstance); Debug.Log(playerToJason);
输出 :
{"playerId":"8484239823","playerLoc":"Powai","playerNick":"Random Nick"}
序列化B部分 :
使用public static string ToJson(object obj, bool prettyPrint);
Json public static string ToJson(object obj, bool prettyPrint);
方法过载。 简单地传递给JsonUtility.ToJson
函数将格式化数据。 将下面的输出与上面的输出进行比较。
Player playerInstance = new Player(); playerInstance.playerId = "8484239823"; playerInstance.playerLoc = "Powai"; playerInstance.playerNick = "Random Nick"; //Convert to Jason string playerToJason = JsonUtility.ToJson(playerInstance, true); Debug.Log(playerToJason);
输出 :
{ "playerId": "8484239823", "playerLoc": "Powai", "playerNick": "Random Nick" }
反序列化A部分 :
反序列化 json与public static T FromJson(string json);
方法过载。
string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}"; Player player = JsonUtility.FromJson<Player>(jsonString); Debug.Log(player.playerLoc);
部分B的反序列化 :
使用public static object FromJson(string json, Type type);
反序列化 Json public static object FromJson(string json, Type type);
方法过载。
string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}"; Player player = (Player)JsonUtility.FromJson(jsonString, typeof(Player)); Debug.Log(player.playerLoc);
C部分的反序列化
反序列化 public static void FromJsonOverwrite(string json, object objectToOverwrite);
方法。 当使用JsonUtility.FromJsonOverwrite
,将不会创build该反序列化对象的新实例。 它将重新使用您传入的实例并覆盖其值。
这是有效的,应尽可能使用。
Player playerInstance; void Start() { //Must create instance once playerInstance = new Player(); deserialize(); } void deserialize() { string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}"; //Overwrite the values in the existing class instance "playerInstance". Less memory Allocation JsonUtility.FromJsonOverwrite(jsonString, playerInstance); Debug.Log(playerInstance.playerLoc); }
2.多个数据(arraysJSON)
你的Json包含多个数据对象。 例如playerId
出现。 Unity的JsonUtility
不支持数组,因为它仍然是新的,但是你可以使用这个人的一个辅助类来使用JsonUtility
来处理数组 。
创build一个名为JsonHelper
的类。 直接从下面复制JsonHelper。
public static class JsonHelper { public static T[] FromJson<T>(string json) { Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(json); return wrapper.Items; } public static string ToJson<T>(T[] array) { Wrapper<T> wrapper = new Wrapper<T>(); wrapper.Items = array; return JsonUtility.ToJson(wrapper); } public static string ToJson<T>(T[] array, bool prettyPrint) { Wrapper<T> wrapper = new Wrapper<T>(); wrapper.Items = array; return JsonUtility.ToJson(wrapper, prettyPrint); } [Serializable] private class Wrapper<T> { public T[] Items; } }
序列化Json数组 :
Player[] playerInstance = new Player[2]; playerInstance[0] = new Player(); playerInstance[0].playerId = "8484239823"; playerInstance[0].playerLoc = "Powai"; playerInstance[0].playerNick = "Random Nick"; playerInstance[1] = new Player(); playerInstance[1].playerId = "512343283"; playerInstance[1].playerLoc = "User2"; playerInstance[1].playerNick = "Rand Nick 2"; //Convert to Jason string playerToJason = JsonHelper.ToJson(playerInstance, true); Debug.Log(playerToJason);
输出 :
{ "Items": [ { "playerId": "8484239823", "playerLoc": "Powai", "playerNick": "Random Nick" }, { "playerId": "512343283", "playerLoc": "User2", "playerNick": "Rand Nick 2" } ] }
Json数组反序列化 :
string jsonString = "{\r\n \"Items\": [\r\n {\r\n \"playerId\": \"8484239823\",\r\n \"playerLoc\": \"Powai\",\r\n \"playerNick\": \"Random Nick\"\r\n },\r\n {\r\n \"playerId\": \"512343283\",\r\n \"playerLoc\": \"User2\",\r\n \"playerNick\": \"Rand Nick 2\"\r\n }\r\n ]\r\n}"; Player[] player = JsonHelper.FromJson<Player>(jsonString); Debug.Log(player[0].playerLoc); Debug.Log(player[1].playerLoc);
输出 :
博万
用户2
如果这是来自服务器的Json数组,并且您没有手动创build它 :
您可能需要添加{"Items":
在收到的string前,然后添加}
在它的末尾。
我为此做了一个简单的function:
string fixJson(string value) { value = "{\"Items\":" + value + "}"; return value; }
那么你可以使用它:
string jsonString = fixJson(yourJsonFromServer); Player[] player = JsonHelper.FromJson<Player>(jsonString);
3.不使用类来反序列化jsonstring&&使用数字属性反序列化Json
这是一个以数字或数字属性开头的Json。
例如:
{ "USD" : {"15m" : 1740.01, "last" : 1740.01, "buy" : 1740.01, "sell" : 1744.74, "symbol" : "$"}, "ISK" : {"15m" : 179479.11, "last" : 179479.11, "buy" : 179479.11, "sell" : 179967, "symbol" : "kr"}, "NZD" : {"15m" : 2522.84, "last" : 2522.84, "buy" : 2522.84, "sell" : 2529.69, "symbol" : "$"} }
Unity的JsonUtility
不支持这个,因为“15m”属性以数字开头。 一个类variables不能以一个整数开始。
从Unity的wiki下载SimpleJSON.cs
。
要获得USD的“15m”属性:
var N = JSON.Parse(yourJsonString); string price = N["USD"]["15m"].Value; Debug.Log(price);
要获得ISK的“15m”属性:
var N = JSON.Parse(yourJsonString); string price = N["ISK"]["15m"].Value; Debug.Log(price);
要获得NZD的“15m”物业:
var N = JSON.Parse(yourJsonString); string price = N["NZD"]["15m"].Value; Debug.Log(price);
其余的Json属性不能以数字开头,可以由Unity的JsonUtility处理。
4.故障排除JsonUtility:
序列化与JsonUtility.ToJson
时的问题?
使用JsonUtility.ToJson
获取空string还是“ {}
”?
A。 确保该类不是一个数组。 如果是这样,请使用JsonHelper.ToJson
而不是JsonUtility.ToJson
的helper类。
B。 将[Serializable]
添加到要序列化的类的顶部。
C。 从class级中删除属性。 例如,在variables中, public string playerId { get; set; }
public string playerId { get; set; }
public string playerId { get; set; }
删除 { get; set; }
{ get; set; }
{ get; set; }
。 Unity不能序列化这个。
使用JsonUtility.FromJson
进行反序列化时JsonUtility.FromJson
问题?
A。 如果你得到Null
,请确保Json不是Json数组。 如果是,请使用JsonHelper.FromJson
而不是JsonHelper.FromJson
来使用上面的帮助器类。
B。 如果在反[Serializable]
时候得到NullReferenceException
,那么在类的顶部添加[Serializable]
。
C。还有其他问题,请确认您的json是否有效。 去这里这个网站粘贴JSON。 它应该告诉你,如果JSON是有效的。 它也应该与Json生成适当的类。 只要确保删除删除 { get; set; }
{ get; set; }
{ get; set; }
从每个variables,也添加[Serializable]
生成的每个类的顶部。
Newtonsoft.Json:
如果由于某种原因,必须使用Newtonsoft.Json,然后在这里查看Unity的分叉版本。 请注意,如果使用某些function,您可能会遇到崩溃。 小心。
回答你的问题 :
你的原始数据是
[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]
添加 {"Items":
在它的前面 ,然后添加 }
在它的末尾 。
代码来做到这一点:
serviceData = "{\"Items\":" + serviceData + "}";
现在你有:
{"Items":[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]}
要将多个数据从PHP作为数组 序列化 ,现在可以这样做了
public player[] playerInstance; playerInstance = JsonHelper.FromJson<player>(serviceData);
playerInstance[0]
是你的第一个数据
playerInstance[1]
是你的第二个数据
playerInstance[2]
是你的第三个数据
或类中的数据与playerInstance[0].playerLoc
, playerInstance[1].playerLoc
, playerInstance[2].playerLoc
……
在访问它之前,可以使用playerInstance.Length
来检查长度。
注意: 删除 { get; set; }
{ get; set; }
{ get; set; }
从player
类。 如果你有{ get; set; }
{ get; set; }
{ get; set; }
,它不会工作。 Unity的JsonUtility
不适用于定义为属性的类成员。
不要修剪[]
,你应该罚款。 []
确定一个JSON数组,这正是你所需要的能够迭代其元素。
就像@Maximiliangerhardt所说的那样,MiniJson没有适当的反序列化能力。 我使用JsonFx,像一个魅力。 与[]
player[] p = JsonReader.Deserialize<player[]>(serviceData); Debug.Log(p[0].playerId +" "+ p[0].playerLoc+"--"+ p[1].playerId + " " + p[1].playerLoc+"--"+ p[2].playerId + " " + p[2].playerLoc);
你必须添加[System.Serializable]
到PlayerItem
类,像这样:
using System; [System.Serializable] public class PlayerItem { public string playerId; public string playerLoc; public string playerNick; }
假设你有这样的JSON
[ { "type": "qrcode", "symbol": [ { "seq": 0, "data": "HelloWorld9887725216", "error": null } ] } ]
要统一parsing上面的JSON,可以像这样创buildJSON模型。
[System.Serializable] public class QrCodeResult { public QRCodeData[] result; } [System.Serializable] public class Symbol { public int seq; public string data; public string error; } [System.Serializable] public class QRCodeData { public string type; public Symbol[] symbol; }
然后简单地按以下方式parsing…
var myObject = JsonUtility.FromJson<QrCodeResult>("{\"result\":" + jsonString.ToString() + "}");
现在您可以根据您的需要修改JSON / CODE。 https://docs.unity3d.com/Manual/JSONSerialization.html
- 如何以编程方式检查C#中checkedlistbox中的项目?
- 为什么使用函数名称作为函数指针相当于将函数名称的地址运算符?
- UnauthorizedAccessException无法parsingDirectory.GetFiles失败
- 为什么通用ICollection在.NET 4.5中实现IReadOnlyCollection?
- 识别NHibernate代理类
- 无法在控制台应用的“主要”方法中指定“asynchronous”修饰符
- C ++编译器何时开始考虑string文字字符转义中的两个以上的hex数字?
- 在Moq Callback()调用中设置variables值
- 如何更改winform DataGridview标题的颜色?