Object reference error while reading specific JSON string? - c#

I have used JSON to C# Class Converter and it generates the following Class:
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":""}}}
From Above JSON all the data is read but 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"}}},
Error:
Object Reference not set to an instance of object.
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; }
}
}
Reading 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;
Any Idea?

If you're getting Object Reference not set to an instance of object. that means that you're trying to access properties on an object that is null. Since you said it happens on this line:
lblfmiVersion.Text = resobj.fmi.invalid_nameattribute.version;
that could mean that any of resobj, resobj.fmi, or resobj.fmi.invalid_nameattribute are null. Ignoring the fact that you should have proper null checks in your code to help avoid this situation, let's ask the question, why would any of these objects be null if deserialization succeeded? Perhaps some of the data was not deserialized correctly after all.
When deserializing using Json.Net, it is important to know that if any members of a class do not have matching properties in the JSON, those members will be skipped by Json.Net and thus retain their default values, e.g. null. So one possible reason that you have a null is that the name of a property in your class does not match what is in the JSON.
If we take a look at your Fmi class, one thing that jumps out right away is that it has a suspiciously named property called invalid_nameattribute. In the JSON, there is no such property. Instead, there is a property called #attributes. Your FmipLockStatusDevice class has the same problem. Since they didn't match up, these properties did not get populated during deserialization, so they are null.
So how can we fix this?
This is simple enough: add a [JsonProperty] attribute to your class properties to map them to the right JSON properties. (While you're at it, you might also consider changing the names of those properties in your C# class to something that actually makes sense, like "Attributes".)
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; }
}
OK, now that you have a solution, you should ask yourself, how did you get into this situation in the first place, and how can you avoid it in the future?
You said you used json2csharp.com to generate your classes. You need to be aware that this tool is not foolproof, and will not always be able to generate correct classes to work with your JSON. This is true whenever the JSON property names contain punctuation characters or spaces or start with numbers, because these cannot be turned into valid C# property names. In these cases, json2csharp.com will generate a property name that starts with "invalid". You need to look for these, and make manual adjustments to your classes to fix the issues. Do not just blindly use the generated classes and assume they are correct.
Hope this helps.

Related

Deserialize json c# with CRM 365 API

So, I've made classes like this:
public class Values
{
public string odata_context { get; set; }
public List<ContactsDeserialize> keyValues { get; set; }
}
public class ContactsDeserialize : IDisposable
{
public string odata_etag { get; set; }
public Guid contactid { get; set; }
public string crimson_title { get; set; }
public string firstname { get; set; }
public string lastname { get; set; }
public DateTime? createdon { get; set; }
public DateTime? birthdate { get; set; }
public string emailaddress1 { get; set; }
public string mobilephone { get; set; }
public string address1_line1 { get; set; }
public string address1_line2 { get; set; }
public string address1_line3 { get; set; }
public string address1_city { get; set; }
public string address1_postalcode { get; set; }
public string address1_telephone1 { get; set; }
}
but when I try to deserialise
this by using
Values ContactData = JsonConvert.DeserializeObject<Values>(jsonstring);
it's return null.
Can not find out the reason
Thanks
Your class fields a little bit differ to original json fields, so if you want to use this you need to put attributes to your fields to provide correct json fields i.e
[JsonProperty("#odata.etag")]
public string odata_etag { get; set; }
for more details see the documentation article
Could be that you need to intialise the keyValues list in a constructor.
public class Values
{
public Values()
{
keyValues = new List<ContactsDeserialize>();
}
public string odata_context {get; set; }
public List<ContactsDeserialize> keyValues { get; set; }
}
Alos the names of you objects should match exactly what the json return unless you define what it maps to in an attribute. Both odata_context and keyValues are named slightly different to how they are returned in the json.
You declare public List<ContactsDeserialize> keyValues { get; set; } in Class Values,but the node of your json is value.

I am getting error while converting json to object

i am trying to convert JSON to object following is my json
{"entity":"event","account_id":"acc_8yTsyb2WJOlcka","event":"payment.captured","contains":["payment"],"payload":{"payment":{"entity":{"id":"pay_AKR45WLH0g1ANu","entity":"payment","amount":100,"currency":"INR","status":"captured","order_id":"order_AKR41LsWIgOAB1","invoice_id":null,"international":false,"method":"netbanking","amount_refunded":0,"refund_status":null,"captured":true,"description":"Admission Fees","card_id":null,"bank":"SBIN","wallet":null,"vpa":null,"email":"xxxxx.xxxx#xxx.xxx","contact":"xxxxx","notes":{"address":"NA","merchant_order_id":"2516"},"fee":2,"tax":0,"error_code":null,"error_description":null,"created_at":1528367383}}},"created_at":1528367384}
and the code I am trying to convert to object is
jsonString = JsonConvert.SerializeObject(documentContents);
RazorPayPayload desJsonString = JsonConvert.DeserializeObject<RazorPayPayload>(jsonString);
and the classes where I want to deserialized
public class RazorPayPayload
{
public string entity { get; set; }
public string account_id { get; set; }
public string events { get; set; }
public List<string> contains { get; set; }
public payments payload { get; set; }
public string created_at { get; set; }
}
public class payments
{
public Entities payment { get; set; }
}
public class notes
{
public string address { get; set; }
public string merchant_order_id { get; set; }
public string source { get; set; }
}
public class Entities
{
public Entity entity { get; set; }
}
public class Entity
{
public string id { get; set; }
public string entity { get; set; }
public string amount { get; set; }
public string currency { get; set; }
public string order_id { get; set; }
public string invoice_id { get; set; }
public string international { get; set; }
public string method { get; set; }
public string amount_refunded { get; set; }
public string refund_status { get; set; }
public string captured { get; set; }
public string description { get; set; }
public string card_id { get; set; }
public string bank { get; set; }
public string wallet { get; set; }
public string vpa { get; set; }
public string email { get; set; }
public string contact { get; set; }
public notes notes { get; set; }
public string fee { get; set; }
public string tax { get; set; }
public string error_code { get; set; }
public string error_description { get; set; }
}
I am getting the error "Error converting value to type 'FeePayr_Razor_Webhook.RazorPayPayload'"
Have you tried changing:
{"entity":"event","account_id":"acc_8yTsyb2WJOlcka","event":
to
{"entity":"event","account_id":"acc_8yTsyb2WJOlcka","events":
That would better match your class definition. Or rename your class field to event.
There is a useful visual studio function for converting a json object to c# classes.
Copy the JSON into the clipboard. (helps if the JSON object properties holds data, to determine the data type)
Go to visual studio and place cursor where you'd like to paste in the c# classes.
click edit => paste special => paste json as classes

Deserialize returns object with all values set to null

String str ="{\"_id\":\"eta_emp_1\",\"_rev\":\"446-195e9341df50aeed33d2cb833420b100\",";
str+="\"channels\":[\"ch_pri-eta_org\"],\"doc_type\":\"emp\",\"downloaded\":true,";
str+="\"eta_code\":\"abhi\",\"f_name\":\"Abhilash\",\"isactive\":true,";
str+="\"isadmin\":true,\"l_name\":\"Dhondalkar\",";
str+="\"lat\":17.69967582522918,\"lon\":75.89857880026102,";
str+="\"m_name\":\"Dheeraj\",\"mod_at\":1494693566503,\"mod_by\":\"eta_emp_1\",";
str+="\"org_id\":\"eta_org\",\"pwd\":\"abcde\",";
str+="\"reported_by\":[\"e27f41e7-5b84-4c86-838e-97598b4d20a0\",\"8daa0901-f6e8-4fdd-b41c-658aa901899d\",";
str+="\"9bf72297-481c-4d59-a0f4-d5549cb60e27\",\"2e5ce994-2cfb-4e62-88f8-ff1d3a069ca0\"]}";
UserDetails userDetails = JsonConvert.DeserializeObject<UserDetails>(str);
public class UserDetails
{
String _id{get;set;}
String _rev { get; set; }
String[] channels{get;set;}
String doc_type{get;set;}
bool downloaded{get;set;}
String eta_code{get;set;}
String f_name{get;set;}
bool isactive { get; set; }
bool isadmin { get; set; }
long l_name{get;set;}
long lat{get;set;}
String lon{get;set;}
String m_name{get;set;}
long mod_at{get;set;}
String mod_by{get;set;}
String org_id{get;set;}
String pwd{get;set;}
String[] reported_by{get;set;}
}
All values are set to null.
Not able to figure out issue. Pl help
This class should work:
public class UserDetails
{
public string _id { get; set; }
public string _rev { get; set; }
public List<string> channels { get; set; }
public string doc_type { get; set; }
public bool downloaded { get; set; }
public string eta_code { get; set; }
public string f_name { get; set; }
public bool isactive { get; set; }
public bool isadmin { get; set; }
public string l_name { get; set; }
public double lat { get; set; }
public double lon { get; set; }
public string m_name { get; set; }
public long mod_at { get; set; }
public string mod_by { get; set; }
public string org_id { get; set; }
public string pwd { get; set; }
public List<string> reported_by { get; set; }
}
More help:
http://json2csharp.com
Based on my previous experience with JSON.NET, it can be a bit tricky the translation from JSON to the right class. The web site above have provided me all the time the right class. The only exception is the Wikipedia API because it's a dynamic API and you need to do a small trick.
Also, keep in mind all properties must be public because if something is private (like in your question), it is not going to be accessible by the translator or anything else. I hope it's helpful.
Either mark all the properties in your class as public, or explicity add JsonProperty attribute to each property as follows:
public class UserDetails
{
[JsonProperty("_id")]
String _id { get; set; }
...
}
When using Json Validator I got "The root JSON data must represent an object or an array", therefore indicating that your JSON is most likey not correct.
This is why the string cannot be serialized to your class, leaving the properties null.
You should show us your serialization process to find out about where the error is.

REST Api returning different object names for the same object, how to handle with RestSharp?

I'm programming a C# implementation for the Qualtrics API (v 2.5) using RestSharp. When calling the method getUserIds, it returns a list of users in JSON format (see the example output below).
The problem/question I face is that for each user object (the list of objects under Result) it generates a different id, starting with URH_. When using json2csharp it assumes ofcourse that it's always a different class, while in fact it's absolutely the same one as you can see in the output, and as is stated in the documentation of the api. How can I best resolve this - so that I can make a class UserData that I can reuse? Because now I obviously always see these random URH_ prefixed classes in each response.
NOTE: I was thinking I could try to massage the response first, and when I get the response replace each URH_ prefixed object under the root Result object with a "UserData" string - but I feel this is breaking the rules a bit, and thought the community would have a better solution?
Below is the raw JSON output (note that I removed sensitive information):
{"Meta":{"Status":"Success","Debug":""},"Result":{"URH_3wpA9pxGbE0c7Xu":{"DivisionID":null,"UserName":"user.name#domain.com","UserFirstName":"x","UserLastName":"x","UserAccountType":"UT_4SjjZmbPphZGKDq","UserEmail":"x.x#x.x","UserAccountStatus":"Active"},"URH_57vQr8MVXgpcPUo":{"DivisionID":"DV_XXXXXXXX","UserName":"jxxxx#xx.xxx","UserFirstName":"X","UserLastName":"X","UserAccountType":"UT_BRANDADMIN","UserEmail":"xxxx#xxg.xxx","UserAccountStatus":"Active"},"URH_6ujW1EP0QJOUaoI":{"DivisionID":"DV_XXXXXXXYZ","UserName":"x.xckx#xxx.xyz","UserFirstName":"x","UserLastName":"x","UserAccountType":"UT_XXXXXABCD","UserEmail":"c.c#cc.com","UserAccountStatus":"Active"}}}
This is what I get when generating a model using json2csharp:
public class Meta
{
public string Status { get; set; }
public string Debug { get; set; }
}
public class URH3wpA9pxGbE0c7Xu
{
public object DivisionID { get; set; }
public string UserName { get; set; }
public string UserFirstName { get; set; }
public string UserLastName { get; set; }
public string UserAccountType { get; set; }
public string UserEmail { get; set; }
public string UserAccountStatus { get; set; }
}
public class URH57vQr8MVXgpcPUo
{
public string DivisionID { get; set; }
public string UserName { get; set; }
public string UserFirstName { get; set; }
public string UserLastName { get; set; }
public string UserAccountType { get; set; }
public string UserEmail { get; set; }
public string UserAccountStatus { get; set; }
}
public class URH6ujW1EP0QJOUaoI
{
public string DivisionID { get; set; }
public string UserName { get; set; }
public string UserFirstName { get; set; }
public string UserLastName { get; set; }
public string UserAccountType { get; set; }
public string UserEmail { get; set; }
public string UserAccountStatus { get; set; }
}
public class Result
{
public URH3wpA9pxGbE0c7Xu URH_3wpA9pxGbE0c7Xu { get; set; }
public URH57vQr8MVXgpcPUo URH_57vQr8MVXgpcPUo { get; set; }
public URH6ujW1EP0QJOUaoI URH_6ujW1EP0QJOUaoI { get; set; }
}
public class RootObject
{
public Meta Meta { get; set; }
public Result Result { get; set; }
}
It's simple - just use Dictionary<string, UserData> generic type for Result field:
public class Response
{
public Meta Meta { get; set; }
public Dictionary<string, UserData> Result { get; set; }
}
public class Meta
{
public string Status { get; set; }
public string Debug { get; set; }
}
public class UserData
{
public string DivisionID { get; set; }
public string UserName { get; set; }
public string UserFirstName { get; set; }
public string UserLastName { get; set; }
public string UserAccountType { get; set; }
public string UserEmail { get; set; }
public string UserAccountStatus { get; set; }
}

JSON.NET Resolving Nested Data Types

I'm new to JSON.NET, and I've been playing with the new Marvel API that was recently released.
When I call this API it will return the following JSON Data Structure:-
{
"code": 200,
"status": "Ok",
"etag": "f0fbae65eb2f8f28bdeea0a29be8749a4e67acb3",
"data":
{
"offset": 0,
"limit": 20,
"total": 30920,
"count": 20,
"results": [{array of objects}}]
}
}
I can create Classes for this Data like this :
public class Rootobject
{
public int code { get; set; }
public string status { get; set; }
public string etag { get; set; }
public Data data { get; set; }
}
public class Data
{
public int offset { get; set; }
public int limit { get; set; }
public int total { get; set; }
public int count { get; set; }
public Result[] results { get; set; }
}
public class Result
{
}
Now, my issue. The Results that come back from the API can relate to different Objects, it could be results relating to Characters, Comics, Series etc. The objects all hold different properties.
I need to be able to swap out the Result Class properties based on the Entity Type that the results relate too?
Can this actually be done?
You can use var jObj = JObject.Parse(jsonString) then discover what object type it is by which properties are available on the object.
jObj["someComicSpecificProperty"] != null
However this is not full proof and will need to be done on a per object basis for the results array.
An alternate approach I have seen people use is to have a property on the object that is "typeName".
However the root cause of this problem is that you are trying to strongly type a property that is not strongly typed. I would really recommend splitting these different types of results out into different properties so that you don't have this problem.
As promised, I've posted the anser to this problem. It turns out that the JSON response has nested data covering all related data-types, very much like a relational database.
I found something really cool, I basically made a request to the API and converted its response to a string. I then used the debugger to take a copy of the contents to the clipboard.
I created a new Class and Called it MarvelResponse.
I added the NewtonSoft.Json directive to the file, and used the Paste Special option from Edit Menu in VS2012. Here you can paste the option "Paste as JSON CLasses".
After some minor tweaking here is what it provided :-
namespace Kaiser.Training.Data.JSONClasses
{
public class MarvelResponse
{
public int code { get; set; }
public string status { get; set; }
public string etag { get; set; }
public Data data { get; set; }
}
public class Data
{
public int offset { get; set; }
public int limit { get; set; }
public int total { get; set; }
public int count { get; set; }
public Result[] results { get; set; }
}
public class Result
{
public int id { get; set; }
public string name { get; set; }
public string description { get; set; }
public DateTime modified { get; set; }
public Thumbnail thumbnail { get; set; }
public string resourceURI { get; set; }
public Comics comics { get; set; }
public Series series { get; set; }
public Stories stories { get; set; }
public Events events { get; set; }
public Url[] urls { get; set; }
}
public class Thumbnail
{
public string path { get; set; }
public string extension { get; set; }
}
public class Comics
{
public int available { get; set; }
public string collectionURI { get; set; }
public ComicResourceUriItem[] items { get; set; }
public int returned { get; set; }
}
public class ComicResourceUriItem
{
public string resourceURI { get; set; }
public string name { get; set; }
}
public class Series
{
public int available { get; set; }
public string collectionURI { get; set; }
public SeriesResourceItem[] items { get; set; }
public int returned { get; set; }
}
public class SeriesResourceItem
{
public string resourceURI { get; set; }
public string name { get; set; }
}
public class Stories
{
public int available { get; set; }
public string collectionURI { get; set; }
public StoriesResourceItem[] items { get; set; }
public int returned { get; set; }
}
public class StoriesResourceItem
{
public string resourceURI { get; set; }
public string name { get; set; }
public string type { get; set; }
}
public class Events
{
public int available { get; set; }
public string collectionURI { get; set; }
public EventsResourceUriItem[] items { get; set; }
public int returned { get; set; }
}
public class EventsResourceUriItem
{
public string resourceURI { get; set; }
public string name { get; set; }
}
public class Url
{
public string type { get; set; }
public string url { get; set; }
}
}
This was a huge help! Hope someone else finds it useful.

Categories

Resources