Я очень новичок в C#, поэтому прошу прощения, если это не имеет никакого смысла!C# Parsing JSON w/Newtonsoft
Использование консольного приложения C#, мне трудно анализировать подробный ответ json и присваивать значения json переменным. Я думал, что все работает, десериализуя json до строки до 200 итераций (я буду геокодировать более миллиона адресов), я получил ответ с пустым массивом результатов, который разбил мое приложение. Теперь я пытаюсь использовать новый подход, используя JObject, JProperty и JToken, но не имея большой удачи.
Мой пример JSON является следующим ..
{
"input": {
"address_components": {
"number": "123",
"predirectional": "E",
"street": "Main",
"suffix": "St",
"formatted_street": "E Main St",
"city": "Mesa",
"state": "AZ",
"zip": "85209",
"country": "US"
},
"formatted_address": "123 E Main St, Mesa, AZ 85209"
},
"results": [
{
"address_components": {
"number": "123",
"predirectional": "E",
"street": "Main",
"suffix": "St",
"formatted_street": "E Main Ave",
"city": "Mesa",
"county": "Maricopa County",
"state": "AZ",
"zip": "85209",
"country": "US"
},
"formatted_address": "123 E Main St, Mesa, AZ 85209",
"location": {
"lat": 33.123456,
"lng": -111.123456
},
"accuracy": 1,
"accuracy_type": "range_interpolation",
"source": "TIGER\/Line\u00ae dataset from the US Census Bureau",
"fields": {
"congressional_district": {
"name": "Congressional District 5",
"district_number": 5,
"congress_number": "114th",
"congress_years": "2015-2017"
},
"state_legislative_districts": {
"senate": {
"name": "State Senate District 16",
"district_number": "16"
},
"house": {
"name": "State House District 16",
"district_number": "16"
}
},
"school_districts": {
"unified": {
"name": "Gilbert Unified District",
"lea_code": "0403400",
"grade_low": "PK",
"grade_high": "12"
}
},
"timezone": {
"name": "MST",
"utc_offset": -7,
"observes_dst": false
}
}
},
{
"address_components": {
"number": "123",
"predirectional": "E",
"street": "Main",
"suffix": "St",
"formatted_street": "E Main St",
"city": "Mesa",
"county": "Maricopa County",
"state": "AZ",
"zip": "85209",
"country": "US"
},
"formatted_address": "123 E Main St, Mesa, AZ 85209",
"location": {
"lat": 33.123456,
"lng": -111.123456
},
"accuracy": 0.8,
"accuracy_type": "range_interpolation",
"source": "TIGER\/Line\u00ae dataset from the US Census Bureau",
"fields": {
"congressional_district": {
"name": "Congressional District 5",
"district_number": 5,
"congress_number": "114th",
"congress_years": "2015-2017"
},
"state_legislative_districts": {
"senate": {
"name": "State Senate District 16",
"district_number": "16"
},
"house": {
"name": "State House District 16",
"district_number": "16"
}
},
"school_districts": {
"unified": {
"name": "Gilbert Unified District",
"lea_code": "0403400",
"grade_low": "PK",
"grade_high": "12"
}
},
"timezone": {
"name": "MST",
"utc_offset": -7,
"observes_dst": false
}
}
}
]
}
JSon, который сломал мой исходный код ..
{
"input": {
"address_components": {
"number": "123",
"predirectional": "E",
"street": "Main",
"suffix": "St",
"formatted_street": "E Main St",
"city": "Mesa",
"state": "AZ",
"zip": "85209",
"country": "US"
},
"formatted_address": "123 E Main St, Mesa, AZ 85209"
},
"results": []
}
Исходный код ..
Uri uri = new Uri("https://api.geocod.io/v1/geocode?q=" + geocodioAddress + "&fields=cd,stateleg,school,timezone&api_key=" + app_key);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Method = WebRequestMethods.Http.Get;
request.Accept = "application/json";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string output = reader.ReadToEnd();
response.Close();
dynamic array = JsonConvert.DeserializeObject(output);
if (array.results[0] != null)
{
// cont.
}
ГЗС ошибка «Индекс был вне пределов досягаемости. Должен быть неотрицательным и меньше размера коллекции». Ошибка возникает при «if (array.results [0]! = Null)».
Теперь я уверен, что это не самый лучший подход в любом случае, так что я думал, что я хотел бы попробовать что-то новое (найденный здесь: C# Parsing JSON array of objects) ..
Uri uri = new Uri("https://api.geocod.io/v1/geocode?q=" + geocodioAddress + "&fields=cd,stateleg,school,timezone&api_key=" + app_key);
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Method = WebRequestMethods.Http.Get;
request.Accept = "application/json";
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
string json = reader.ReadToEnd();
response.Close();
var resultObjects = AllChildren(JObject.Parse(json))
.First(c => c.Type == JTokenType.Array && c.Path.Contains("results"))
.Children<JObject>();
foreach (JObject result in resultObjects)
{
foreach (JProperty property in result.Properties())
{
JToken _county = property.Value.SelectToken("county");
string county = Convert.ToString(_county);
// cont.
}
}
Это выглядело очень многообещающим, за исключением трех вещей.
Я не хочу анализировать результаты [1]. Вы заметите в ответе json, что второй экземпляр результатов имеет более низкий балл точности. И когда я не изменяю значения lat/lng, чтобы скрыть свой личный адрес, эти два экземпляра отличаются от второго, что гораздо менее точно.
Хотя я успешно получил значение для округа выше, я не могу получить ответ для «formatted_address», а также каждый раз сбрасывается значение через цикл foreach.
В разделе «поля» имеется несколько объектов с тем же именем. Например ..
JToken _county = property.Value.SelectToken ("name");
Как выбрать, какое «имя» я ищу? школьный округ, часовой пояс, район Конгресса и т. д.
Опять же, я прошу прощения за такой длинный пост. Я работаю над этим всю неделю, и только когда я подумал, что это выяснилось, один глупый адрес не должен возвращать никаких результатов и сломать все! Я очень ценю помощь людей гораздо умнее меня ... обратная сторона работы из дома, другие мозгов, чтобы забрать :)
Ваш первый бит кода хорош, но вы должны попробовать десериализовать класс, используя 'JsonConvert.DeserializeObject (string)'. Таким образом, вы можете получить доступ к значениям статически. Вы можете проверить, есть ли хотя бы один элемент массива, выполнив 'array! = Null && array.Length> 0'. Надеюсь это поможет! –
Привет Тим. Это Матиас из geocod.io. Один из наших клиентов разделил этот пример, который он написал для десериализации ответа. Не стесняйтесь проверить здесь: https://gist.github.com/btompkins/8722291 – CodeMonkey