C# Parsing JSON w/ Newtonsoft
本文关键字:Newtonsoft JSON Parsing | 更新日期: 2023-09-27 18:37:11
我对 c# 很陌生,所以如果这没有任何意义,我深表歉意!
使用 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#解析JSON对象数组)。
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 响应中注意到,第二个结果实例的准确性分数较低。当我不更改纬度/液化值来隐藏我的个人地址时,这两个实例是不同的,第二个实例的准确性要低得多。
虽然我成功获得了上述县的值,但我无法获得"formatted_address"的响应,并且每次通过 foreach 循环重置值。
在"字段"部分中,有多个具有相同名称的对象。例如。。
JToken _county = 属性。Value.SelectToken("name");
如何选择我要查找的"名称"? 学区、时区、国会选区等。
再次,我很抱歉这么长的帖子。我整个星期都在研究这个问题,就在我认为我已经弄清楚的时候,一个愚蠢的地址必须返回没有结果并破坏一切!!我真的很感谢比我聪明得多的人的帮助......在家工作的缺点,没有其他大脑可以挑选:)
如果您查看破坏代码的数据:
{
{
"input": {
..
},
"formatted_address": "123 E Main St, Mesa, AZ 85209"
},
"results": []
}
您已results
定义为空数组。换句话说,它包含零元素。因此,尝试访问此数组中的第一个元素(索引 0 处)会导致您得到的错误。
而不是您正在执行的测试:
if (array.results[0] != null)
{
// cont.
}
你应该做:
if (array.Length != 0)
{
// cont.
}
这是因为"结果"对象存在,但它是空的(长度为零)。