Home > Enterprise >  Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'ConsoleAppTest01.Location&#
Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'ConsoleAppTest01.Location&#

Time:12-01

Cannot figure out why I'm getting this exception:

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'ConsoleAppTest01.Location' because the type requires a JSON object

The JSON response can be viewed here (no worries I'll update the API key later): http://dataservice.accuweather.com/locations/v1/postalcodes/search?apikey=RUuBWKtaUKRJC4GtWkjGDuhStOZblr78&q=12065

Here's what my code looks like:

public class Location
{
    public Locality[] Property1 { get; set; }
}

public class Locality
{
    public int Version { get; set; }
    public string Key { get; set; }
    public string Type { get; set; }
    public int Rank { get; set; }
    public string LocalizedName { get; set; }
    public string EnglishName { get; set; }
    public string PrimaryPostalCode { get; set; }
    public Region Region { get; set; }
    public Country Country { get; set; }
    public Administrativearea AdministrativeArea { get; set; }
    public Timezone TimeZone { get; set; }
    public Geoposition GeoPosition { get; set; }
    public bool IsAlias { get; set; }
    public Parentcity ParentCity { get; set; }
    public Supplementaladminarea[] SupplementalAdminAreas { get; set; }
    public string[] DataSets { get; set; }
}

public class Region
{
    public string ID { get; set; }
    public string LocalizedName { get; set; }
    public string EnglishName { get; set; }
}

public class Country
{
    public string ID { get; set; }
    public string LocalizedName { get; set; }
    public string EnglishName { get; set; }
}

public class Administrativearea
{
    public string ID { get; set; }
    public string LocalizedName { get; set; }
    public string EnglishName { get; set; }
    public int Level { get; set; }
    public string LocalizedType { get; set; }
    public string EnglishType { get; set; }
    public string CountryID { get; set; }
}

public class Timezone
{
    public string Code { get; set; }
    public string Name { get; set; }
    public float GmtOffset { get; set; }
    public bool IsDaylightSaving { get; set; }
    public DateTime NextOffsetChange { get; set; }
}

public class Geoposition
{
    public float Latitude { get; set; }
    public float Longitude { get; set; }
    public Elevation Elevation { get; set; }
}

public class Elevation
{
    public Metric Metric { get; set; }
    public Imperial Imperial { get; set; }
}

public class Metric
{
    public float Value { get; set; }
    public string Unit { get; set; }
    public int UnitType { get; set; }
}

public class Imperial
{
    public float Value { get; set; }
    public string Unit { get; set; }
    public int UnitType { get; set; }
}

public class Parentcity
{
    public string Key { get; set; }
    public string LocalizedName { get; set; }
    public string EnglishName { get; set; }
}

public class Supplementaladminarea
{
    public int Level { get; set; }
    public string LocalizedName { get; set; }
    public string EnglishName { get; set; }
}

and in the Main()

static void Main(string[] args)
    {
        string apiUrl = $"http://dataservice.accuweather.com";
        
        Console.Write("Enter ZipCode: ");
        string zip = Console.ReadLine();

        string locationUri = $"{apiUrl}/locations/v1/postalcodes/search?apikey={APIKEY}&q={zip}";            

        Location locationData = GetLocation<Location>(locationUri);
                    
    }

and GetLocation() looks like:

   protected static T GetLocation<T>(string uri)
    {
        T result;

        HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
        request.Method = "GET";

        HttpWebResponse response = request.GetResponse() as HttpWebResponse;

        using (StreamReader reader = new StreamReader(response.GetResponseStream()))
        {
            string jsonString = reader.ReadToEnd();
            result = JsonConvert.DeserializeObject<T>(jsonString);
        }

        return result;
    }

CodePudding user response:

The Json returned from accuweather starts with a [ so it must be an array but you've told JsonConvert to deserialize an object Location; this is not an array (the json would have to start with a { for object deser to work)

A quick look (on a cellphone, hard to digest the full json and map it to your classes 100% on a small screen) seems like you want to deser a Locality[], not a Location..

..but I'd advise you to just paste your json into http://QuickType.io and use the classes it makes for you; they'll work off the bat

Or even better; it's quite likely accuweather publish a swagger/open api spec that you can run through something like AutoRest or nSwag and get those tools to generate a full set of client stubs for you so it's literally a single line of code to send an object to the api, get the response, read and deser it and give you the answer

CodePudding user response:

Your json root is List, not object. Try to use this

List<Locality> locationData = GetLocation<List<Locality>>(locationUri);
  • Related