#c# #json #deserialization
#c# #json #десериализация
Вопрос:
Не могу понять, почему я получаю это исключение:
Невозможно десериализовать текущий массив JSON (например, [1,2,3]) в тип ‘ConsoleAppTest01.Местоположение’, поскольку для этого типа требуется объект JSON
Ответ JSON можно посмотреть здесь (не беспокойтесь, я обновлю ключ API позже): http://dataservice.accuweather.com/locations/v1/postalcodes/search?apikey=RUuBWKtaUKRJC4GtWkjGDuhStOZblr78amp;q=12065
Вот как выглядит мой код:
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; }
}
и в 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}amp;q={zip}";
Location locationData = GetLocation<Location>(locationUri);
}
и getLocation() выглядит так:
protected static T GetLocation<T>(string uri)
{
T resu<
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 resu<
}
Ответ №1:
Json, возвращаемый из accuweather, начинается с a [
, поэтому он должен быть массивом, но вы сказали JsonConvert десериализовать местоположение объекта; это не массив (json должен начинаться с a {
, чтобы объект deser работал)
Быстрый взгляд (на мобильном телефоне трудно переварить полный json и сопоставить его с вашими классами на 100% на маленьком экране) кажется, что вы хотите изменить a Locality[]
, а не a Location
..
..но я бы посоветовал вам просто вставить свой json в http://QuickType.io и используйте классы, которые он создает для вас; они будут работать с места в карьер
Или даже лучше; вполне вероятно, что accuweather опубликует спецификацию swagger / open api, которую вы можете запустить через что-то вроде AutoRest или nSwag и заставить эти инструменты генерировать для вас полный набор клиентских заглушек, так что это буквально одна строка кода для отправки объекта в api, получения ответа, прочитайте и удалите его и дайте вам ответ
Комментарии:
1. Спасибо! это было действительно полезно.
Ответ №2:
Ваш корень json — это список, а не объект. Попробуйте использовать это
List<Locality> locationData = GetLocation<List<Locality>>(locationUri);