Невозможно десериализовать массив JSON в тип foo

Я пытаюсь разобрать данные из api-канала oodle.com с помощью библиотеки JSON.NET. Часть JSON-строки ответа для десериализации имеет следующую структуру «location»:

"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 Data. Это отлично работает, когда в местоположении есть действительные данные, но не работает, когда местоположение представлено как пустой массив. Я попытался добавить атрибуты (NullValueHandling & Required), чтобы установить экземпляр местоположения как 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; }
     }

person Ash    schedule 11.09.2010    source источник
comment
В вашем первом примере нет массивов, но во втором есть пустой ... заботится ли JSON.NET, какие данные о местоположении (один объект или массив объектов)?   -  person Cᴏʀʏ    schedule 11.09.2010
comment
Хорошая точка зрения. Я только что это заметил. Я свяжусь с поставщиком данных (oodle.com dev api), чтобы попытаться получить объяснение. Похоже, что тип данных в этом случае отличается от погоды, имеет данные или значение null. Есть ли структура данных, которая может содержать и то, и другое? Есть ли у JSON.NET трюк, который сообщает ему сериализовать его в LocationData, если у него есть данные, в противном случае просто поместите NULL, если это пустой массив?   -  person Ash    schedule 12.09.2010
comment
Проблема оказалась в построении JSON из PHP. объект местоположения был определен как хэш $ somehash = array (); и заполняется как: if ($ foo) {$ location {'foo'} = $ foo; } в php json_encode преобразует $ somehash в somehash [], хотя $ somehash предназначен для использования в качестве хешированного объекта вместо массива ... Таким образом, решение состоит не в создании экземпляра переменной $ somehash = array (); пока у вас не будет первого элемента для заполнения. Это будет сериализовать объект json как NULL вместо массива.   -  person Ash    schedule 14.09.2010


Ответы (1)


Вы можете написать собственный преобразователь для типа LocationData, чтобы преобразовывать токены массива в null.

Что-то вроде:

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 {...}
person Paul Tyng    schedule 10.11.2011