Issue with Deserialization with JSON with C# - c#

I have looked over example after example after example and none of my attempts have worked.
I'm attempting to deserialize this JSON return:
{
"status": "success",
"data": {
"result": "match",
"id_user": 26564,
"dob_match": null,
"first_name_match": null,
"last_name_match": null
},
"code": 200
}
Here is my JSON object class declaration:
[DataContract]
internal class DccCoachApi
{
[DataMember]
public string result { get; set; }
public string id_user { get; set; }
public string dob_match { get; set; }
public string first_name_match { get; set; }
public string last_name_match { get; set; }
}
In my stream method, my streamRead variable is filled with:
{"status":"success","data":{"result":"match","id_user":26564,"dob_match":null,"first_name_match":null,"last_name_match":null},"code":200}
Method 1 does not populate coachId:
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(streamRead)))
{
// Deserialization from JSON
var deserializer = new DataContractJsonSerializer(typeof(DccCoachApi));
var dccObj = (DccCoachApi)deserializer.ReadObject(ms);
coachId = dccObj.id_user;
}
Nor does method 2:
DccCoachApi coach = new JavaScriptSerializer().Deserialize<DccCoachApi>(streamRead);
coachId = coach.id_user;
nor does method 3:
JavaScriptSerializer js = new JavaScriptSerializer();
DccCoachApi dccObj = js.Deserialize<DccCoachApi>(streamRead);
coachId = dccObj.id_user;
nor does method 4:
dynamic dccObject = js.Deserialize<dynamic>(streamRead);
coachId = dccObject["id_user"];
The hard error that gets produced when i pull the value directly off method 4 is:
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary. at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
Methods 1-3 do not hit a hard error, however they populate coachId with no data.
Can somebody please let me know what i'm doing wrong?

You can simply generate proper classes here: http://json2csharp.com/
This is how it should look like you don't need the DataMember Attributes, it might confuse the serializer to only de-serialize this single property:
public class Data
{
public string result { get; set; }
public int id_user { get; set; }
public object dob_match { get; set; }
public object first_name_match { get; set; }
public object last_name_match { get; set; }
}
public class RootObject
{
public string status { get; set; }
public Data data { get; set; }
public int code { get; set; }
}
Code:
var deserializer = DataContractJsonSerializer(typeof(RootObject));
var root = (RootObject)deserializer.ReadObject(ms);
var coachId = root.data.id_user;

I revised the code to look like this, and it is dumping my value perfectly. Thanks much to everyone who helped me reach the solution. Plutonix, thanks as well for the paste special 411. I had no idea that existed. VERY useful!
using (var reader = new StreamReader(webResponse.GetResponseStream()))
{
var streamRead = reader.ReadToEnd();
reader.Close();
using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(streamRead)))
{
JavaScriptSerializer js = new JavaScriptSerializer();
DccCoachRootobject dccObj = js.Deserialize<DccCoachRootobject>(streamRead);
coachId = dccObj.data.id_user.ToString();
}
}

Related

Using Jsonseralizer when the value comes across with 'Null'

I have a json string I am trying to serialize into an object, but some of the values are 'null', not null as in empty, but actually the word null, unfortunately those are not string values. I attempted to add the defaultignorecondition whenwritingnull, but that alone doesn't seem to work. The error is:
InvalidOperationException: Cannot get the value of a token type 'Null' as a number
My code:
var settings = new JsonSerializerOptions
{
DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull
};
gdata = JsonSerializer.Deserialize<List<gasData>>(response.Content, settings);
Example from the json raw data:
"no_offset":0.0000,"no_units":"ppb","so2_sensor_serial_number":null,"so2_state":"Not Fitted","so2_prescaled":null
Try this code, it is working properly
var json = "{\"no_offset\":0,\"no_units\":\"ppb\",\"so2_sensor_serial_number\":null,\"so2_state\":\"Not Fitted\",\"so2_prescaled\":null}";
var data = System.Text.Json.JsonSerializer.Deserialize<Data>(json);
class
public partial class Data
{
[JsonPropertyName("no_offset")]
public long? NoOffset { get; set; }
[JsonPropertyName("no_units")]
public string NoUnits { get; set; }
[JsonPropertyName("so2_sensor_serial_number")]
public long? So2SensorSerialNumber { get; set; }
[JsonPropertyName("so2_state")]
public string So2State { get; set; }
[JsonPropertyName("so2_prescaled")]
public object So2Prescaled { get; set; }
}

c# JSONConvert.DeserializeObject<List<RootObject>> returns nulls

I am trying to deserialize an HTTPWebRequest response (Json) to a c# object/class, but am having trouble. A collection with 10 instances of the object are returned, and all the objects are null.
Here is the json:
[
{
"id":2227,
"user_id":441,
"grades":
{"html_url":"https://...",
"current_score":91.26,
"current_grade":null,
},
"sis_account_id":"11",
"user":
{"id":441,
"name":"Nicholas Bailey",
}
},
Here are the classes:
public class Grade
{
public string html_url { get; set; }
public decimal current_score { get; set; }
public string current_grade { get; set; }
}
public class User
{
public int id { get; set; }
public string name { get; set; }
}
public class Enrollment
{
public int id { get; set; }
public int user_id { get; set; }
public Grade grades { get; set; }
public string sis_account_id { get; set; }
public User user { get; set; }
}
public class RootObject
{
public Enrollment enrollment { get; set; }
}
And here is my code:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://(some uri)");
WebResponse response = request.GetResponse();
StreamReader sr = new StreamReader(response.GetResponseStream());
string content = sr.ReadToEnd();
JsonSerializerSettings settings = new JsonSerializerSettings();
settings.MetadataPropertyHandling = MetadataPropertyHandling.Ignore;
var outObject = JsonConvert.DeserializeObject<List<RootObject>>(content, settings);
I have been looking at a lot of code on google but have not found a situation that is close to mine. Also, I'm a bit green on generic collections. The code runs fine but in the debugger the "outObject" contains 10 entries, each with an "Enrollment" object that is null.
I also have tried this with json that has well over 10 entries, but it still comes up with 10. But I'm more focused on the nulls at this point (One thing at a time!). For the sake of brevity I have removed several entries in the json, but the main pattern (an enrollment object with a grades object and a user object embedded in it) remains.
Any help would be much appreciated. Thanks.
Deserialize to List<Enrollment> not List<RootObject>:
var enrollment = JsonConvert.DeserializeObject<List<Enrollment>>(content, settings);
The first JSON object in the root array has properties "id", "user_id" and so on that correspond to the members of Enrollment. Conversely there is no property "enrollment" in the JSON anywhere.
Sample fiddle.
Update
You asked, I tried this and now I'm getting an exception "Error converting value {null} to type 'System.Int32'. Path '[0].associated_user_id', line 1, position 165." associated_user_id was removed for brevity but I will add it back into my code. Any ideas?
Somewhere your data model you must have the following member (field or property):
public int associated_user_id;
Change this to a nullable:
public int? associated_user_id;

Converting .Net object to JSON missing most properties

I'm playing around with Web API 4 for the first time and preparing to hook up connection to a MongoDb. I've defined some simple objects to represent the models but when I try to return a collection of them from the GET request of my API only one property is being included in the resulting JSON object.
public class Topic : Entity
{
public string Name { get; set; }
public List<Topic> Parents { get; set; }
public List<Topic> Children { get; set; }
public List<ContentNode> ContentNodes { get; set; }
}
public class ContentNode
{
public enum ContentNodeType { VIDEO, TEXT, AUDIO };
public ContentNodeType ContentType { get; set; }
public string Url { get; set; }
public List<int> Scores { get; set; }
public List<Link> Links { get; set; }
public List<string> Comments { get; set; }
}
public string Get()
{
List<Topic> topics = new List<Topic>();
var programming = new Topic()
{
Id = "1",
Name = "Programming"
};
var inheritanceVideo = new ContentNode()
{
ContentType = ContentNode.ContentNodeType.VIDEO,
Url = "http://youtube.com",
Scores = new List<int>() {
4, 4, 5
},
Comments = new List<string>() {
"Great video about inheritance!"
}
};
var oop = new Topic()
{
Id = "2",
Name = "Object Oriented Programming",
ContentNodes = new List<ContentNode>() {
inheritanceVideo
}
};
programming.Children.Add(oop);
topics.Add(programming);
string test = JsonConvert.SerializeObject(topics);
return test;
}
I'm using the JSON.Net library to serialize the object here but I previously used the default JSON serializer and had the GET return IEnumerable<Topic>. In both cases the JSON being returned is simply:
"[{\"Id\":\"1\"}]"
A browser request for the XML works just fine. According to the documentation for JSON.Net it doesn't seem like there should be a problem serializing these classes to JSON. Any thoughts on why this isn't working? It doesn't seem like I should need to apply explicit attributes for every member.

JavaScriptDeseializer : Can not serialize array

My application is asp.net. I have to send some values back to server. For this I create a object serialize it and send it to server. At server I try to de-serialize it
Following is my code
[Serializable]
public class PassData
{
public PassData()
{
}
public List<testWh> SelectedId { get; set; }
public string SelectedControlClientId { get; set; }
public string GroupTypeId { get; set; }
public string SectionTypeId { get; set; }
}
[Serializable]
public class testWh
{
public testWh()
{
}
public string Id { get; set; }
}
JavaScriptSerializer serializer = new JavaScriptSerializer();
//this can not serialize the SelectedId and the count remains 0
PassData data = serializer.Deserialize<PassData>(jsonString);
//this serialize in an anonymous object with key value pair
var data2 = serializer.DeserializeObject(textHiddenArguments.Text);
Following is my Json Serialized String
{
"SelectedId":{"0":"ABCD","1":"JKLM"},
"SelectedControlClientId":"YTUTOOO",
"GroupTypeId":3,
"SectionTypeId":"1"
}
quotes escaped string
"{\"SelectedId\":{\"0\":\"ABCD\",\"1\":\"JKLM\"},\"SelectedControlClientId\":\"YTUTOOO\",\"GroupTypeId\":3,\"SectionTypeId\":\"1\"}"
My Problem is Selected Id is array of testWH object. But when I try to desrialize it, the SelectedId property of PassData which is list does not get serialized and count remains zero.
I tried using array instead of List, which gave an exception "no parameter less constructor..."
Could any one explain the what I am doing wrong here ?
The key problem here is that the JSON doesn't match the objects you have constructed. You can see this by writing the data you want and serializing:
var obj = new PassData
{
SelectedId = new List<testWh>
{
new testWh { Id = "ABCD"},
new testWh { Id = "JKLM"}
},
GroupTypeId = "3",
SectionTypeId = "1",
SelectedControlClientId = "YTUTOOO"
};
string jsonString = serializer.Serialize(obj);
which gives JSON like:
{"SelectedId":[{"Id":"ABCD"},{"Id":"JKLM"}],
"SelectedControlClientId":"YTUTOOO","GroupTypeId":"3","SectionTypeId":"1"}
So now you need to decide which you want to change; the JSON or the classes. The following alternative class works fine with your original JSON, for example:
public class PassData
{
public Dictionary<string,string> SelectedId { get; set; }
public string SelectedControlClientId { get; set; }
public string GroupTypeId { get; set; }
public string SectionTypeId { get; set; }
}

Missing JSON field causes crashes?

My Code goes like this:
using (StreamReader streamReader1 = new StreamReader(response.GetResponseStream()))
{
string resultString = streamReader1.ReadToEnd();
var ser = new DataContractJsonSerializer(typeof(RootObject));
var stream = new MemoryStream(Encoding.Unicode.GetBytes(resultString));
DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(RootObject));
RootObject myBook = (RootObject)jsonSerializer.ReadObject(stream);
Deployment.Current.Dispatcher.BeginInvoke(() => Shops.ItemsSource = myBook.SearchResponse.Spell.Results); }
public class Query
{
public string SearchTerms { get; set; }
}
public class Result
{ [DataMember(IsRequired=false)]
public string Value { get; set; }
}
public class Spell
{
[DataMember(IsRequired = false)]
public int Total { get; set; }
[DataMember(IsRequired = false)]
public List<Result> Results { get; set; }
}
public class SearchResponse
{
public bool IsRequired { get; set; }
public string Version { get; set; }
public Query Query { get; set; }
public Spell Spell { get; set; }
}
public class RootObject
{
public SearchResponse SearchResponse { get; set; }
}
IF JSON DATA EXISTS
{"SearchResponse":{"Version":"2.0","Query":{"SearchTerms":"mispell"},"Spell":{"Total":1,"Results":[{"Value":"misspell"}]}}}
IF JSON DATA DOES NOT EXIST
{"SearchResponse":{"Version":"2.0","Query":{"SearchTerms":"mispel"}}}
The thing is, if Bing doesn't detect a wrong word, it crashes and gives me an error like NullReferenceException. I have tried to do an IF statement looking at the stream for if it's value is blank but doesn't seem to work.
Any ideas?
If you receive a JSON answer without the Spell part, the Spell property in SearchResponse will be null. If it's null, you may not dereference it like this:
myBook.SearchResponse.Spell.Results
(This hasn't anything to do with JSON. It's how C# works.)
So instead of:
Shops.ItemsSource = myBook.SearchResponse.Spell.Results
you probably want to write:
if (myBook.SearchResponse.Spell = null)
Shops.ItemsSource = myBook.SearchResponse.Spell.Results;
else
Shops.ItemsSource = new List<Result>();
For your next question: It would be very helpful if your questions would show the exact error message including the stack trace (or at least the exact line where it occurred).
Use [DataMember(IsRequired=false)], MSDN: http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datamemberattribute.isrequired.aspx

Categories