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