读取特定JSON字符串时出现对象引用错误?

我已经使用JSON到C#类转换器 ,它生成以下类:

JSON

{"ios_info":{"serialNumber":"F2LLMBNJFFF","imeiNumber":"01388400413235","meid":"","iccID":"8901410427640096045","firstUnbrickDate":"11\/27\/13","lastUnbrickDate":"11\/27\/13","unbricked":"true","unlocked":"false","productVersion":"7.1.2","initialActivationPolicyID":"23","initialActivationPolicyDetails":"US AT&T Puerto Rico and US Virgin Islands Activation Policy","appliedActivationPolicyID":"23","appliedActivationDetails":"US AT&T Puerto Rico and US Virgin Islands Activation Policy","nextTetherPolicyID":"23","nextTetherPolicyDetails":"US AT&T Puerto Rico and US Virgin Islands Activation Policy","macAddress":"ACFDEC6C988A","bluetoothMacAddress":"AC:FD:EC:6C:98:8B","partDescription":"IPHONE 5S SPACE GRAY 64GB-USA"},"fmi":{"@attributes":{"version":"1","deviceCount":"1"},"fmipLockStatusDevice":{"@attributes":{"serial":"F2LLMBNJFFFQ","imei":"013884004132355","isLocked":"true","isLost":"false"}}},"product_info":{"serialNumber":"F2LLMBNJFFF","warrantyStatus":"Apple Limited Warranty","coverageEndDate":"11\/25\/14","coverageStartDate":"11\/26\/13","daysRemaining":"497","estimatedPurchaseDate":"11\/26\/13","purchaseCountry":"United States","registrationDate":"11\/26\/13","imageURL":"http:\/\/service.info.apple.com\/parts\/service_parts\/na.gif","explodedViewURL":"http:\/\/service.info.apple.com\/manuals-ssol.html","manualURL":"http:\/\/service.info.apple.com\/manuals-ssol.html","productDescription":"iPhone 5S","configDescription":"IPHONE 5S GRAY 64GB GSM","slaGroupDescription":"","contractCoverageEndDate":"11\/25\/15","contractCoverageStartDate":"11\/26\/13","contractType":"C1","laborCovered":"Y","limitedWarranty":"Y","partCovered":"Y","notes":"Covered by AppleCare+ - Incidents Available","acPlusFlag":"Y","consumerLawInfo":{"serviceType":"","popMandatory":"","allowedPartType":""}}} 

从JSON以上读取所有数据,但only the line at which i get error is in reading the JSON is:

 fmi":{"@attributes":{"version":"1","deviceCount":"1"},"fmipLockStatusDevice":{"@attributes":{"serial":"F2LLMBNJFFFQ","imei":"013884004132355","isLocked":"true","isLost":"false"}}}, 

错误:

对象引用未设置为对象的实例。

 public class AppleAPI { public IosInfo ios_info { get; set; } public ProductInfo product_info { get; set; } public Fmi fmi { get; set; } public class IosInfo { public string serialNumber { get; set; } public string imeiNumber { get; set; } public string meid { get; set; } public string iccID { get; set; } public string firstUnbrickDate { get; set; } public string lastUnbrickDate { get; set; } public string unbricked { get; set; } public string unlocked { get; set; } public string productVersion { get; set; } public string initialActivationPolicyID { get; set; } public string initialActivationPolicyDetails { get; set; } public string appliedActivationPolicyID { get; set; } public string appliedActivationDetails { get; set; } public string nextTetherPolicyID { get; set; } public string nextTetherPolicyDetails { get; set; } public string macAddress { get; set; } public string bluetoothMacAddress { get; set; } public string partDescription { get; set; } } public class ConsumerLawInfo { public string serviceType { get; set; } public string popMandatory { get; set; } public string allowedPartType { get; set; } } public class ProductInfo { public string serialNumber { get; set; } public string warrantyStatus { get; set; } public string coverageEndDate { get; set; } public string coverageStartDate { get; set; } public string daysRemaining { get; set; } public string estimatedPurchaseDate { get; set; } public string purchaseCountry { get; set; } public string registrationDate { get; set; } public string imageURL { get; set; } public string explodedViewURL { get; set; } public string manualURL { get; set; } public string productDescription { get; set; } public string configDescription { get; set; } public string slaGroupDescription { get; set; } public string contractCoverageEndDate { get; set; } public string contractCoverageStartDate { get; set; } public string contractType { get; set; } public string laborCovered { get; set; } public string limitedWarranty { get; set; } public string partCovered { get; set; } public string notes { get; set; } public string acPlusFlag { get; set; } public ConsumerLawInfo consumerLawInfo { get; set; } } public class Fmi { public Attributes invalid_nameattribute { get; set; } public FmipLockStatusDevice fmipLockStatusDevice { get; set; } } public class FmipLockStatusDevice { public Attributes2 invalid_nameattribute2 { get; set; } } public class Attributes { public string version { get; set; } public string deviceCount { get; set; } } public class Attributes2 { public string serial { get; set; } public string imei { get; set; } public string isLocked { get; set; } public string isLost { get; set; } } } 

阅读JSON:

 string responseText = string.Empty; AppleAPI appobj = new AppleAPI(); responseText = appobj.VerifyAppleESN(newEsn); var resobj = JsonConvert.DeserializeObject(responseText.Replace("@",string.Empty)); lblSerialNumber.Text = resobj.product_info.serialNumber; . . lblappliedActivationDetails.Text = resobj.ios_info.appliedActivationDetails; . . //getting here error below line: Object ref notset to instance of object lblfmiVersion.Text = resobj.fmi.invalid_nameattribute.version; 

任何的想法?

如果您Object Reference not set to an instance of object. 这意味着您正在尝试访问对象为null的属性。 既然你说它发生在这一行:

 lblfmiVersion.Text = resobj.fmi.invalid_nameattribute.version; 

这可能意味着resobjresobj.fmiresobj.fmi.invalid_nameattribute中的任何一个都为null。 忽略你应该在代码中进行适当的空检查以帮助避免这种情况的事实,让我们问一个问题,如果反序列化成功,为什么这些对象中的任何一个都为null? 也许有些数据毕竟没有正确反序列化。

使用Json.Net进行反序列化时,重要的是要知道如果类的任何成员在JSON中没有匹配的属性,那么Json.Net将跳过这些成员,从而保留它们的默认值,例如null 。 因此,您有一个null的一个可能原因是您的类中的属性名称与JSON中的属性名称不匹配。

如果我们看看你的Fmi类,立即跳出的一件事就是它有一个名为invalid_nameattribute的可疑命名属性。 在JSON中,没有这样的属性。 相反,有一个名为@attributes的属性。 您的FmipLockStatusDevice类具有相同的问题。 由于它们不匹配,因此在反序列化期间不会填充这些属性,因此它们为空。

那我们怎么解决这个问题呢?

这很简单:在类属性中添加[JsonProperty]属性,将它们映射到正确的JSON属性。 (当你在它的时候,你也可以考虑将你的C#类中的那些属性的名称改为实际有意义的东西,比如“属性”。)

 public class Fmi { [JsonProperty("@attributes")] public Attributes invalid_nameattribute { get; set; } public FmipLockStatusDevice fmipLockStatusDevice { get; set; } } public class FmipLockStatusDevice { [JsonProperty("@attributes")] public Attributes2 invalid_nameattribute2 { get; set; } } 

好了,既然你有一个解决方案,你应该问问自己,你是如何首先陷入这种情况的,以及如何在将来避免这种情况?

你说你用json2csharp.com来生成你的类。 您需要注意,此工具并非万无一失,并且无法始终生成正确的类来使用您的JSON。 只要JSON属性名称包含标点符号或空格或以数字开头,就是这样,因为这些不能转换为有效的C#属性名称。 在这些情况下,json2csharp.com将生成以“invalid”开头的属性名称。 您需要查找这些内容,并对类进行手动调整以解决问题。 不要盲目地使用生成的类并假设它们是正确的。

希望这可以帮助。