使用C#和Newtonsoft提取JSON中RiskId与Occupants列表报错解决
问题:提取JSON中的RiskId和Occupants时触发ArgumentNullException
尝试用C#和Newtonsoft从目标JSON中提取所有RiskId和Occupants列表,执行以下代码时抛出异常:
var jsonObj = (JObject)JsonConvert.DeserializeObject(jsonstring); var jsonResult = jsonObj.SelectToken("Risks.RiskId").Select(m => m.Value<string>());
异常信息:System.ArgumentNullException: 'Value cannot be null. Parameter name: source'
目标JSON数据:
{ "Header": { "MatchType": "Exact", "TotalResultCount": 2, "PreviousPageUrl": null, "NextPageUrl": null, "AvailableProductsForRequestedAddress": "https://prometrixapiuat.iso.com/uw/address/productList?City=MONTEBELLO&State=CA&StreetName=423+W+OLYMPIC+BLVD&Zip=90640" }, "Risks": [ { "RiskId": "64CX99016399", "BuildingDescription": "MONTEBELLO PLASTICS INC (1S)", "SurveyDates": { "ScheduleAppliedDate": "04/21/1999", "LatestPhoneSurveyDate": "", "OnsiteSurveyDate": "05/01/1999" }, "Location": { "Latitude": null, "Longitude": null, "Address": { "StreetAddress1": "423 W OLYMPIC BLVD", "City": "MONTEBELLO", "PostalCity": "MONTEBELLO", "State": "CA", "Zip": "90640", "Zip4": "5225", "County": "LOS ANGELES" }, "AlternateAddresses": [] }, "Occupants": [ { "Name": "MFG STORAGE - PACKAGING MATERIALS", "OccupantId": "15" } ], "ProductListUrl": "https://prometrixapiuat.iso.com/uw/Risk/64CX99016399/ProductList", "YearBuilt": 1960, "FireProtectionArea": "MONTEBELLO" }, { "RiskId": "64CX99016400", "BuildingDescription": "MONTEBELLO PLASTICS INC (1S)", "SurveyDates": { "ScheduleAppliedDate": "04/21/1999", "LatestPhoneSurveyDate": "", "OnsiteSurveyDate": "05/01/1999" }, "Location": { "Latitude": null, "Longitude": null, "Address": { "StreetAddress1": "423 W OLYMPIC BLVD", "City": "MONTEBELLO", "PostalCity": "MONTEBELLO", "State": "CA", "Zip": "90640", "Zip4": "5225", "County": "LOS ANGELES" }, "AlternateAddresses": [] }, "Occupants": [ { "Name": "MFG STORAGE - PACKAGING MATERIALS", "OccupantId": "15" } ], "ProductListUrl": "https://prometrixapiuat.iso.com/uw/Risk/64CX99016400/ProductList", "YearBuilt": 1960, "FireProtectionArea": "MONTEBELLO" } ] }
问题原因
SelectToken("Risks.RiskId") 无法找到对应节点,返回null。因为JSON中的Risks是数组类型,不能直接通过.访问数组元素的子属性,必须先获取数组本身,再遍历数组中的每个对象来提取RiskId和Occupants。后续调用Select时,源为null,触发ArgumentNullException。
解决方法
方法1:使用JObject/JArray手动遍历(无强类型)
先获取Risks数组,再逐个遍历每个Risk对象,分别提取目标字段:
var jsonObj = (JObject)JsonConvert.DeserializeObject(jsonstring); // 获取Risks数组,先做null检查 var risksArray = jsonObj.SelectToken("Risks") as JArray; if (risksArray == null) return; foreach (JObject risk in risksArray) { // 提取RiskId string riskId = risk["RiskId"].Value<string>(); Console.WriteLine($"RiskId: {riskId}"); // 提取Occupants数组并遍历 var occupantsArray = risk["Occupants"] as JArray; if (occupantsArray != null) { Console.WriteLine("Occupants:"); foreach (JObject occupant in occupantsArray) { string name = occupant["Name"].Value<string>(); string occupantId = occupant["OccupantId"].Value<string>(); Console.WriteLine($" - 名称:{name},ID:{occupantId}"); } } Console.WriteLine("---"); }
方法2:强类型序列化(推荐)
定义与JSON结构匹配的实体类,直接序列化后遍历,代码更简洁且类型安全:
第一步:定义实体类
// 只保留需要的字段,其余字段可根据需求添加 public class RiskResponse { public List<Risk> Risks { get; set; } } public class Risk { public string RiskId { get; set; } public List<Occupant> Occupants { get; set; } } public class Occupant { public string Name { get; set; } public string OccupantId { get; set; } }
第二步:序列化并遍历
var response = JsonConvert.DeserializeObject<RiskResponse>(jsonstring); if (response?.Risks == null) return; foreach (var risk in response.Risks) { Console.WriteLine($"RiskId: {risk.RiskId}"); if (risk.Occupants != null) { Console.WriteLine("Occupants:"); foreach (var occupant in risk.Occupants) { Console.WriteLine($" - 名称:{occupant.Name},ID:{occupant.OccupantId}"); } } Console.WriteLine("---"); }
内容的提问来源于stack exchange,提问作者user2938930
相关产品推荐
相关产品推荐

