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

时间:2014-07-17 09:11:44

标签: c# json json-deserialization

我使用了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;

任何想法?

1 个答案:

答案 0 :(得分:1)

如果您获得Object Reference not set to an instance of object.,则表示您正在尝试访问空对象的属性。既然你说它发生在这一行:

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

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

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

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

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

这很简单:在类属性中添加[JsonProperty]属性,将它们映射到正确的JSON属性。 (虽然您正在考虑它,但您也可以考虑将C#类中这些属性的名称更改为实际有意义的内容,例如&#34;属性&#34;。)

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

希望这有帮助。

相关问题