1

我正在使用 Newtonsoft JSON Converter 反序列化一些 JSON 文本,但我有一个小问题,这是有时我从 Web 服务返回给我的对象数组,而其他时候它只是一个对象,让我给你是我的意思的一个例子:

{
   "T":{
      "S":"054",
      "T":"8",
      "D":"548"
   }
}

一个是数组,而另一个只是一个对象。

{
   "T":[
      {
         "S":"054",
         "T":"8",
         "D":"548"
      },
      {
         "S":"054",
         "T":"8",
         "D":"548"
      },
      {
         "S":"054",
         "T":"8",
         "D":"548"
      }
   ]
}

当我尝试使用 Newtonsoft 反序列化它时,我收到一个错误,因为它需要一个数组并且有时只接收一个对象,有没有办法解决这个问题?

4

2 回答 2

2

You can check the type of you first property like this :

JObject obj = JObject.Parse(json);
if (obj["T"] is JArray)
{
    // hit on second case
}
else
{
    // hit on first case
}

After that's, you can deserialize you object on List<T> or T.

Hope it's help !

EDIT : With your pastebin classes, I have rebuild them and add a Callback on OnDeserialized :

class JSONResponse
{
    public Line ROOT;
}

class Line
{
    [JsonProperty("Time")]
    public Timestamp Time { get; set; }
    [JsonProperty("S")]
    public List<Station> S { get; set; }
}

class Timestamp
{
    [JsonProperty("@TimeStamp")]
    public string @TimeStamp { get; set; }
}

class Station
{
    [JsonProperty("@Code")]
    public string @Code { get; set; }
    [JsonProperty("@N")]
    public string @N { get; set; }
    [JsonProperty("P")]
    public List<Platform> P { get; set; }
}

class Platform
{
    [JsonProperty("@N")]
    public string @N { get; set; }
    [JsonProperty("@Code")]
    public string @Code { get; set; }

    [JsonProperty("T")]
    public JToken T { get; set; }

    [OnDeserialized]
    internal void OnDeserializedMethod(StreamingContext context)
    {
        if (this.T != null)
        {
            if (this.T is JArray)
            {
                this.Trains = JsonConvert.DeserializeObject<List<Train>>(this.T.ToString());
            }
            else
            {
                Train t = JsonConvert.DeserializeObject<Train>(this.T.ToString());
                this.Trains = new List<Train>() { t };
            }
        }
    }
    public List<Train> Trains;
}

class Train
{
    [JsonProperty("@S")]
    public string @S { get; set; }
    [JsonProperty("@T")]
    public string @T { get; set; }
    [JsonProperty("@D")]
    public string @D { get; set; }
    [JsonProperty("@C")]
    public string @C { get; set; }
    [JsonProperty("@L")]
    public string @L { get; set; }
    [JsonProperty("@DE")]
    public string @DE { get; set; }
}

You will got your trains, on the Platform.Trains property

于 2013-08-08T14:12:54.013 回答
0

如果您只希望有一种对象类型可以反序列化,那么一种选择是将JSON转换为一个数组(如果它只是一个元素)——在尝试反序列化之前。例如

// If only a single element, the JSON will not contain an opening bracket.
if (!str.Contains('['))
{
    var index = str.IndexOf("{",1);  // Ignore first brace.
    var lastIndex = str.LastIndexOf('}'); // Find last brace.
    str = str.Substring(0,index-1) + "[" + 
          str.Substring(index, str.Length - index); // Insert bracket.
    str = str.Substring(0, lastIndex) + "]}"; // Insert bracket.
}

您当然可以将上述优化为单个语句——但这只是让您了解如何在反序列化之前操作字符串。

这还假设您的 JSON 中没有子数组。否则,你会得到误报。

于 2013-08-08T14:20:50.213 回答