【问题标题】:Object reference error while reading specific JSON string?读取特定 JSON 字符串时出现对象引用错误?
【发布时间】:2014-07-17 09:11:44
【问题描述】:

我使用了JSON to C# Class Converter,它生成了以下类:

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<AppleAPI>(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;

有什么想法吗?

【问题讨论】:

    标签: c# json json-deserialization


    【解决方案1】:

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

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

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

    使用 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”开头的属性名称。您需要查找这些,并对您的类进行手动调整以解决问题。不要盲目地使用生成的类并假设它们是正确的。

    希望这会有所帮助。

    【讨论】:

    • 嘿@Brian Rogers!你真的很棒!你是唯一让我知道错误来源的人!并通过解决方案进行了如此详细的解释!简直太棒了!感谢您指出我“不要按原样使用”,我同意所说的!它在第一次尝试时有效!谢谢+1 :)
    • @SHEKHARSHETE 没问题;很高兴我能帮上忙。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多