这是我从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">
在对象中。我还注意到"data"后面跟有[]括号,在更简单的括号中跟有{}括号。
如果有人能链接到一些好的阅读材料,或者对解决方案/正在发生的事情做出很好的解释,我真的很感激
这部分是您遇到的问题的关键:
对象中的。我还注意到"data"后面跟有[]括号,在更简单的括号中跟有{}括号。
在JSON中,
[]
括号包含一个数组{}
方括号包含一个对象
在这两个代码示例中,您都是通过使用par["data"].Children()
循环结果来深入对象的。为了与JSON模型保持一致,JSON.NET为解析对象和数组的子级定义了不同的行为。对象的子对象是其属性,数组的子对象则是其项。
在代码中,jsonparsegas
的输入是一个具有2个属性的简单对象数组,其中jsonparsecoc
的输入是具有多个属性的单个复杂对象。
在jsonparsegas
中,Children()
调用为您提供了一个所有简单气体对象的数组。循环遍历这些对象,并提取每个对象的"gas_id"one_answers"gas_name"值。在您的示例数据中,恰好只有一个gas对象,因此您的代码只执行一次。
在jsonparsecoc
中,Children()
调用实际上为复杂对象的属性提供属性值,因为结果是对象而不是数组。因此,当你循环这个结果时,你不能访问像"valve_maker"这样的东西,因为它们是在复杂对象上定义的,并且你已经进入了valve_maker
的值,然后它就会执行。
解决方案很简单不要循环遍历jsonparsecoc
中的属性。你需要的不是foreach(var child in jObj["data"].Children())
,而是var child = jObj["data"];
。这将为您提供对对象的引用,该对象实际上包含您试图访问的每个属性。
@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);
此处演示:https://dotnetfiddle.net/p0D7ze
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.DescializeObject(JsonString)它将把json转换成合适的对象,请记住结构应该合适,属性名称应该与json属性相同希望它能帮助你