在Unity中对Json和Json数组进行序列化和反序列化

我有一个从PHP文件发送到使用WWW统一的项目列表。 WWW.text看起来像[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]在那里我从string修剪额外的[] 。 当我尝试使用Boomlagoon.JSONparsing它时,只有第一个对象被检索。 我发现我必须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是一个例外。 它支持ListList数组!

如果你需要序列化一个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].playerLocplayerInstance[1].playerLocplayerInstance[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