2016-06-12 304 views
1

这是我从一个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"

中的对象

之间做的差。另外我注意到“数据”后面跟着更简单的括号,而更复杂的是{}。

如果任何人都可以链接到一些很好的阅读材料,或提供一个解决方案/发生了什么的好解释,我真的很感激。

+1

{}是c#中的一个类,[]是一个数组,一个集合,一个列表,[{},{},{}]是一个类的数组,{'array':[]}是一个具有数组属性的类.... –

+2

通常我会说使用http://json2csharp.com/产生一个类结构,然后我们e通用'DeserializeObject <>()'签名来创建一个强类型的结构化结果。但是,您的示例输入在其中包含一些数字作为属性的名称,这在C#对象中是不允许的。这些类型的对象是否具有固定的结构,或者它们是否具有任意数量的属性? – StriplingWarrior

+1

@StriplingWarrior您可以使用[一个属性](http://www.newtonsoft.com/json/help/html/serializationattributes.htm)来覆盖名称。 –

回答

1

这部分是关键,你遇到的问题:

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为解决objectsarrays的子项定义了不同的行为。对象的子对象是它的属性,而数组的子对象是它的项目。

在您的代码中,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"];。这将为您提供对象的参考,该对象实际上包含您尝试访问的每个属性。

+0

哈哈谢谢,这个帮了很多。我忽略了这样一个事实,即更简单的一个是我通过循环的许多事例之一,而复杂的事物只是一件大事,并且不需要循环。 – Lodestone6

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 property 希望它会帮助你

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); 

演示在这里:https://dotnetfiddle.net/p0D7ze

相关问题