簡體   English   中英

使用Newtonsoft.Json反序列化/序列化任意數據類型

[英]Deserialize/Serialize arbitrary data type using Newtonsoft.Json

我有一個數據交換框架,該數據將被格式化為JSON以使用http從服務器傳遞到客戶端。

這是它的基本結構:

{
  status: 0,
  data: {name:"balbala",age:12}
  msg: "OK"
}

要么:

{
  status: 0,
  data: [{name: "balbalba", age:12},{name:"another balbala", age:13}],
  msg: "OK"

}

或如果發生壞事

{
  status: -1,//the error code
  msg: "Sorry, internal error"
}

基本思想是,我們將status用作錯誤代碼,並在進行更多處理之前檢查該錯誤代碼,並且當它不為0僅顯示msg ,它是錯誤的詳細信息,但是在data字段中,我們希望攜帶任意JSON格式(主要是arrayobject(key-values) ,我們可以在Java中使用gson來實現,但是在使用C#我們不知道該怎么做,是否可以使用c#來做到這一點?

這是我目前實現的功能,但有一些錯誤。

//the Response structure Definition.
public class Respose
{
    public int status;
    public object data;
    public string msg;

    public Respose() { }
}

//serialize the HTTP text first time to a Response structure.
Respose resp = JsonConvert.DeserializeObject<Respose>(infoStr);

 //just check the status shutcut the processing when meet with a non-zero err-code
if(resp.status != 0)
{
        Debug.LogWarning(resp.msg);
        yield break;
}
//getting the data as json string so that we could deserialize it again
string levelArrayStr = JsonConvert.SerializeObject(resp.data);

//the real data-load we need.
List<Level> levelsFromServer = JsonConvert.DeserializeObject<List<Level>>(levelArrayStr);

這是錯誤:

JsonSerializationException: Unexpected token when deserializing object: StartObject. Path 'data[0]', line 1, position 21.
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject (System.Object newObject, Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, System.String id) (at C:/Project/Github/Json.Net.Unity3D/src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs:2423)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) (at C:/Project/Github/Json.Net.Unity3D/src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs:497)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal (Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, System.Object existingValue) (at C:/Project/Github/Json.Net.Unity3D/src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs:293)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize (Newtonsoft.Json.JsonReader reader, System.Type objectType, Boolean checkAdditionalContent) (at C:/Project/Github/Json.Net.Unity3D/src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs:167)

您可以使用兩個(或三個)單獨的類進行反序列化,也可以使用JObject

public class Data
{
    public string Name;
    public int Age;
}

const string SINGLE = @"{
  status: 0,
  data: {name: ""balbala"",age:12},
  msg: ""OK""
}";


const string MULTI = @"{
  status: 0,
  data: [{name: ""balbala"",age:12},{name: ""another  balbala"",age:13}],
  msg: ""OK""
}";

const string ERROR = @"{
  status: 1,
  msg: ""Sorry, internal error""
}";

List<Data> loDataList = new List<Data>();
//JObject loJObject = JObject.Parse(ERROR);
//JObject loJObject = JObject.Parse(SINGLE);
JObject loJObject = JObject.Parse(MULTI);
if (loJObject.Value<int>("status") != 0)
{
    Debug.WriteLine(loJObject.Value<string>("msg"));
    return;
}

JToken loDataToken = loJObject["data"];
switch (loDataToken.Type)
{
    case JTokenType.Object:
        loDataList.Add(loJObject["data"].ToObject<Data>());
        break;
    case JTokenType.Array:
        loDataList = loJObject["data"].ToObject<List<Data>>();
        break;
}

foreach (var loData in loDataList)
{
    Debug.WriteLine("Name: {0} Age: {1}", loData.Name, loData.Age);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM