Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot deserialize JSON array into type foo

I am trying to parse out data from oodle.com api feed using the JSON.NET lib. Part of the response JSON string to deserialize has the following 'location' structure:

"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"},

however I've seen instances of location declared as an empty array:

"location":[],

I am trying to deserialize it in a class of type Location Data. This works perfect when location has valid data in it but it does not work well when the location is represented as an empty array. I tried adding the attributes (NullValueHandling & Required) to have set the location instance as null if the data is indeed an empty array but I think these attribs are meant for serialization only. If the array is empty I get an exception

Cannot deserialize JSON array into type 'LocationData'

Is there a way to tell the deserializer to not complain and make the location object null if the array the deserialization fails? Thanks!

[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; }
     }
like image 575
Ash Avatar asked Nov 06 '22 08:11

Ash


1 Answers

You can write a custom converter for the LocationData type to turn array tokens in to null.

Something like:

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;
        }
}

Then just tag the LocationData class:

[JsonConverter(typeof(LocationDataConverter))]
public class LocationData {...}
like image 90
Paul Tyng Avatar answered Nov 09 '22 06:11

Paul Tyng