【问题标题】:Cannot deserialize JSON array into type foo无法将 JSON 数组反序列化为 foo 类型
【发布时间】:2010-09-11 16:57:56
【问题描述】:

我正在尝试使用 JSON.NET 库从 oodle.com api 提要中解析出数据。要反序列化的部分响应 JSON 字符串具有以下“位置”结构:

"location":{
"address":"123 foo Street",
"zip":"94102",
"citycode":"usa:ca:sanfrancisco:downtown",
"name":"San Francisco (Downtown)",
"state":"CA",
"country":"USA",
"latitude":"37.7878",
"longitude":"-122.4101"},

但是我已经看到 location 的实例声明为空数组:

"location":[],

我正在尝试将其反序列化为位置数据类型。当位置中包含有效数据时,这非常有效,但当位置表示为空数组时,它不能很好地工作。如果数据确实是一个空数组,我尝试添加属性(NullValueHandling 和必需)以将位置实例设置为 null,但我认为这些属性仅用于序列化。如果数组为空,我会得到一个异常

Cannot deserialize JSON array into type 'LocationData'

如果反序列化失败的数组,有没有办法告诉反序列化器不要抱怨并使位置对象为空? 谢谢!

[JsonProperty(NullValueHandling = NullValueHandling.Ignore,Required=Required.AllowNull)]
public LocationData location{get;set;}
    ...
public class LocationData  
     {
          public string zip { get; set; }
          public string address { get; set; }
          public string citycode { get; set; }
          public string name { get; set; }
          public string state { get; set; }
          public string country { get; set; }
          public decimal latitude { get; set; }
          public decimal longitude { get; set; }
     }

【问题讨论】:

  • 第一个示例中没有数组,但第二个示例中有一个空数组... JSON.NET 是否关心“位置”数据是什么(单个对象或对象数组)?
  • 好点。我只是注意到了。我将联系数据提供者 (oodle.com dev api) 尝试获得解释。在这种情况下,数据类型似乎与天气不同,有数据或空。是否有可以同时包含两者的数据结构? JSON.NET 是否有一个技巧,告诉它如果有数据则将其序列化为 LocationData,否则如果它是一个空数组,则将其设置为 NULL?
  • 问题原来是 PHP 的 JSON 构造。位置对象被定义为哈希 $somehash = array();它被填充为: if ($foo) { $location{'foo'} = $foo; } 在 php json_encode 中将 $somehash 转换为 somehash[] 即使 $somehash 旨在用作散列对象而不是数组......所以解决方案不是实例化变量 $somehash = array();直到你有第一个要填充的项目。这会将 json 对象序列化为 NULL 而不是数组。

标签: json serialization json.net


【解决方案1】:

您可以为LocationData 类型编写自定义转换器,以将数组标记转换为空。

类似:

public class LocationDataConverter : JsonConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.StartArray)
            {
                reader.Read(); //move to end array
                return null;
            }

            var data = new LocationData();
            serializer.Populate(reader, data);

            return data;
        }
}

然后只需标记 LocationData 类:

[JsonConverter(typeof(LocationDataConverter))]
public class LocationData {...}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-16
    • 2016-04-06
    • 1970-01-01
    • 1970-01-01
    • 2019-03-18
    • 1970-01-01
    • 2013-07-19
    相关资源
    最近更新 更多