我对c#非常陌生,所以我很抱歉如果这没有任何意义!C#解析JSON w/Newtonsoft
使用C#控制台应用程序,我很难分析详细的json响应并将json值分配给变量。我认为我已经通过将json反序列化为一个字符串来工作,直到大约200次迭代(我将对100多个地址进行地理编码),我收到了一个响应,其中有一个空的结果数组,导致应用程序崩溃。现在我正在尝试使用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循环重置该值。
在“fields”部分中,有多个具有相同名称的对象。例如..
JToken _county = property.Value.SelectToken(“name”);
如何选择我要找的哪个“名称”?学区,时区,国会区等。
再次,我很抱歉这么长的帖子。我一整周都在努力研究这个问题,就在我认为自己已经想通了的时候,一个愚蠢的地址不得不返回任何结果并破坏一切!我很欣赏的人比我聪明很多的帮助...在家工作的缺点,没有其他心思挑:)
你的第一个代码是好的,但你应该尝试使用'JsonConvert.DeserializeObject(string)'来反序列化一个类。这样,您可以静态访问这些值。你可以通过'array!= null && array.Length> 0'来检查数组中是否至少有一个项目。希望这可以帮助! –
你好。这是来自geocod.io的Mathias。我们的一位客户分享了他编写的用于反序列化响应的例子。随时检查它在这里:https://gist.github.com/btompkins/8722291 – CodeMonkey