在C#中解析这个JSON对象的正确方法是什么?
这是我从一个GET请求接收的JSON对象:在C#中解析这个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();
}
Cannot access child value on Newtonsoft.Json.Linq.JProperty
我已经尝试了一些不同的东西,我在计算器上找到,但我真的不理解对象的反序列化是如何工作的。更简单的解析工作很好,并允许我将从GET请求收到的所有“gas_name”添加到组合框。 “数据”的第一个“valve_maker”孩子的格式似乎与更类似的JSON对象中的“gas_id”或“gas_name”具有相同的结构,但这是我立即收到错误的地方。如果我在为错误的原因猜测,我会说这有什么用
"valve_maker": []
,并使用
中的对象"gas_id": "ID of the gas"
之间做的差。另外我注意到“数据”后面跟着更简单的括号,而更复杂的是{}。
如果任何人都可以链接到一些很好的阅读材料,或提供一个解决方案/发生了什么的好解释,我真的很感激。
这部分是关键,你遇到的问题:
in the objects. also I notice "data" is followed by [] brackets in the simpler one, and {} in the more complicated one.
在JSON,
-
[]
括起来的数组 -
{}
括起来的对象
在这两个代码示例中,y通过使用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"];
。这将为您提供对象的参考,该对象实际上包含您尝试访问的每个属性。
哈哈谢谢,这个帮了很多。我忽略了这样一个事实,即更简单的一个是我通过循环的许多事例之一,而复杂的事物只是一件大事,并且不需要循环。 – Lodestone6
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 property 希望它会帮助你
@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);
{}是c#中的一个类,[]是一个数组,一个集合,一个列表,[{},{},{}]是一个类的数组,{'array':[]}是一个具有数组属性的类.... –
通常我会说使用http://json2csharp.com/产生一个类结构,然后我们e通用'DeserializeObject ()'签名来创建一个强类型的结构化结果。但是,您的示例输入在其中包含一些数字作为属性的名称,这在C#对象中是不允许的。这些类型的对象是否具有固定的结构,或者它们是否具有任意数量的属性? – StriplingWarrior
@StriplingWarrior您可以使用[一个属性](http://www.newtonsoft.com/json/help/html/serializationattributes.htm)来覆盖名称。 –