这是我从GET请求收到的JSON对象:
{
"data": {
"valve_maker": [],
"water_volume": [
"15L",
"20L",
"..."
],
"cylinder_manufacturer": [
"Tianhai"
],
"qc_stamp": [
"TS"
],
"reference_standard": [
"GB 5099"
],
"production_licence": [
"TS2210752-2016"
],
"valve_production_licence": [
"TSF210030"
],
"rate_of_residual_deformation": {
"1": "<3%",
"2": "<10%"
},
"material_number": {
"1": "30CrMo",
"2": "34CrMo4",
"3": "..."
},
"heat_treatment": {
"1": "...",
"2": "..."
},
"drawing_number": {
"1": "...",
"2": "..."
},
"cylinder_thickness": []
}
现在,我能够使用更简单的结构解析JSON对象,如:
{
"data": [
{
"gas_id": "ID of the gas",
"gas_name": "Gas name"
}
]
使用类似的东西:
private void jsonparsegas(string res)
{
JObject par = JObject.Parse(res);
foreach (JToken data in par["data"].Children())
{
string id = data["gas_id"].ToString();
string name = data["gas_name"].ToString();
if (this.cmbCylType.Items.Contains(name) == false)
{
this.cmbCylType.Items.Add(name);
}
}
}
当我尝试将相同的东西应用于更复杂的JSON对象时,我收到错误:
private void jsonparsecoc(string res)
{
//JObject par = JObject.Parse(res);
var jObj = (JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(res);
foreach (var child in jObj["data"].Children())
{
string vMaker = child["valve_maker"].ToString(); //error thrown here right away
string wVolume = child["water_volume"].ToString();
string cMan = child["cylinder_manufacturer"].ToString();
string QC = child["qc_stamp"].ToString();
string rStandard = child["reference_standard"].ToString();
string pLicence = child["production_licence"].ToString();
string VPL = child["valve_production_licence"].ToString();
string rrd = child["rate_of_residual_deformation"].ToString();
string mNum = child["material_number"].ToString();
string hTreatment = child["heat_treatment"].ToString();
string dNum = child["drawing_number"].ToString();
string cThick = child["cylinder_thickness"].ToString();
}
无法访问Newtonsoft.Json.Linq.JProperty
上的子值
我尝试过在StackOverflow上找到的一些不同的东西,但我真的不明白对象的反序列化是如何工作的。更简单的解析工作得很好,并允许我将从GET请求收到的所有“gas_name”添加到组合框中。 “data”的第一个“valve_maker”子元素的格式似乎与更相似的JSON对象中的“gas_id”或“gas_name”具有相同的结构,但这是我立即收到错误的地方。如果我不得不猜测错误的原因,我会说它与使用
之间的区别有关“valve_maker”:[]
并使用
“gas_id”:“气体的ID”
在对象中。另外我注意到“数据”后面跟着更简单的[]括号,而{}则是更复杂的括号。
如果有人可以链接到一些好的阅读材料,或者提供一个解决方案的正确解释/正在发生什么,我真的很感激。
答案 0 :(得分:1)
这部分是您遇到的问题的关键:
在对象中。另外我注意到“数据”后面跟着更简单的[]括号,而{}则是更复杂的括号。
在JSON,
[]
括号括起一个数组{}
括号括起一个对象在两个代码示例中,您通过使用par["data"].Children()
循环结果来挖掘对象。为了与JSON模型保持一致,JSON.NET为解析objects和arrays的子项定义了不同的行为。对象的子节点是它的属性,数组的子节点是它的项。
在您的代码中,jsonparsegas
的输入是一个包含2个属性的简单对象数组,其中jsonparsecoc
的输入是具有许多属性的单个复杂对象。
在jsonparsegas
中,Children()
调用会为您提供所有简单气体对象的数组。循环遍历这些对象并为每个对象提取“gas_id”和“gas_name”的值。在您的示例数据中,恰好只有一个气体对象,因此您的代码只执行一次。
在jsonparsecoc
中,Children()
调用实际上为复杂对象的属性提供了属性值,因为结果是对象而不是数组。因此,当您遍历此结果时,您无法访问“valve_maker”之类的内容,因为它们是在复杂对象上定义的,并且您已经步入valve_maker
的值然后执行。
解决方案很简单。 不要遍历jsonparsecoc
中的属性。而不是foreach(var child in jObj["data"].Children())
,你需要像var child = jObj["data"];
这样的东西。这将为您提供实际包含您尝试访问的每个属性的对象的引用。
答案 1 :(得分:1)
@smartcaveman很好地解释了代码出了什么问题。但是,如果您为此定义强类型类,则可能会发现您的数据更容易处理:
class RootObject
{
public Data Data { get; set; }
}
class Data
{
[JsonProperty("valve_maker")]
public List<string> ValveMaker { get; set; }
[JsonProperty("water_volume")]
public List<string> WaterVolume { get; set; }
[JsonProperty("cylinder_manufacturer")]
public List<string> CylinderManufacturer { get; set; }
[JsonProperty("qc_stamp")]
public List<string> QCStamp { get; set; }
[JsonProperty("reference_standard")]
public List<string> ReferenceStandard { get; set; }
[JsonProperty("production_licence")]
public List<string> ProductionLicense { get; set; }
[JsonProperty("valve_production_licence")]
public List<string> ValveProductionLicense { get; set; }
[JsonProperty("rate_of_residual_deformation")]
public Dictionary<string, string> RateOfResidualDeformation { get; set; }
[JsonProperty("material_number")]
public Dictionary<string, string> MaterialNumber { get; set; }
[JsonProperty("heat_treatment")]
public Dictionary<string, string> HeatTreatment { get; set; }
[JsonProperty("drawing_number")]
public Dictionary<string, string> DrawingNumber { get; set; }
[JsonProperty("cylinder_thickness")]
public List<string> CylinderThickness { get; set; }
}
您可以将JSON反序列化到您的类中,如下所示:
RootObject obj = JsonConvert.DeserializeObject<RootObject>(json);
答案 2 :(得分:0)
public class Test{
public Data data{get;set;}
}
public class Data{
public List<string> Value_maker{get;set;}
public List<String> Water_Volume{get;set;}
public List<String> cylinder_manufacturer{get;set;}
}
创建类结构,然后使用反序列化 Jsonconvert.DeserializeObject(JsonString) 它将json转换为适当的对象,请记住结构应该是正确的,属性名称应该与您的json属性相同 希望它会帮助你