UWP and nested json objects - c#

I'm trying to deserialize some JSON code in a c# applicatie. I use the DataContractJsonSerializer class to do this. All works fine, until I get nested jsonobjects,
I recieve the following json from an external API:
[{"name":"Beeldscherm","json":"{\"onHomeEnter\":{\"state\":0,\"delay\":0,\"fadeTime\":0,\"active\":false,\"updatedAt\":1487166732440},\"onHomeExit\":{\"state\":0,\"delay\":120,\"fadeTime\":0,\"active\":false,\"updatedAt\":1487163669388},\"onRoomEnter\":{\"state\":1,\"delay\":0,\"fadeTime\":0,\"active\":false,\"updatedAt\":1},\"onRoomExit\":{\"state\":0,\"delay\":120,\"fadeTime\":0,\"active\":false,\"updatedAt\":1},\"onNear\":{\"state\":1,\"delay\":0,\"fadeTime\":0,\"active\":false,\"updatedAt\":1487164911729},\"onAway\":{\"state\":0,\"delay\":2,\"fadeTime\":0,\"active\":false,\"updatedAt\":1487164909184}}","id":"58a44fa04f40b016004ffca2","sphereId":"58a44c0a4f40b016004ffc9d","createdAt":"2017-02-15T13:52:12.783Z","updatedAt":"2017-02-15T12:55:05.332Z"}]
Which I edit with the following code:
responJsonText = responJsonText.Replace("\\", "").Replace("\"{", "{").Replace("}\"", "}");
and it then looks like this:
[{"name":"Beeldscherm","json":{"onHomeEnter":{"state":0,"delay":0,"fadeTime":0,"active":false,"updatedAt":1487166732440},"onHomeExit":{"state":0,"delay":120,"fadeTime":0,"active":false,"updatedAt":1487163669388},"onRoomEnter":{"state":1,"delay":0,"fadeTime":0,"active":false,"updatedAt":1},"onRoomExit":{"state":0,"delay":120,"fadeTime":0,"active":false,"updatedAt":1},"onNear":{"state":1,"delay":0,"fadeTime":0,"active":false,"updatedAt":1487164911729},"onAway":{"state":0,"delay":2,"fadeTime":0,"active":false,"updatedAt":1487164909184}},"id":"58a44fa04f40b016004ffca2","sphereId":"58a44c0a4f40b016004ffc9d","createdAt":"2017-02-15T13:52:12.783Z","updatedAt":"2017-02-15T12:55:05.332Z"}]
and try to parse this using the following classes:
[DataContract]
class Appliance
{
[DataMember]
public String name { get; set; }
[DataMember]
public ApplianceJson json { get; set; }
[DataMember]
public String id { get; set; }
[DataMember]
public String sphereId { get; set; }
[DataMember]
public String createdAt { get; set; }
[DataMember]
public String updatedAt { get; set; }
}
[DataContract]
class ApplianceJson
{
[DataMember]
public ApplianceEvents onHomeEnter { get; set; }
[DataMember]
public ApplianceEvents onHomeExit { get; set; }
[DataMember]
public ApplianceEvents onRoomEnter { get; set; }
[DataMember]
public ApplianceEvents onRoomExit { get; set; }
[DataMember]
public ApplianceEvents onNear { get; set; }
[DataMember]
public ApplianceEvents onAway { get; set; }
}
[DataContract]
class ApplianceEvents
{
[DataMember]
public int state { get; set; }
[DataMember]
public int delay { get; set; }
[DataMember]
public int fadeTime { get; set; }
[DataMember]
public bool active { get; set; }
[DataMember]
public int updatedAt { get; set; }
}
and the following code for the deserialization:
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(List<Appliance>));
MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(responJsonText));
The error I get is:
Exception thrown: 'System.Runtime.Serialization.SerializationException' in System.Private.DataContractSerialization.dll
Exception thrown: 'System.Runtime.Serialization.SerializationException' in mscorlib.ni.dll
Does anybody see something that is wrong and how I could fix it?
Update
I checked the json string and its correct now, I've put the correct version in the question
Update 2
added the original JSON

if you notice the Original Json, You can see " is not \" but if you go deep into json, the Json Node itself has " as \". So i cleaned up all \" first and then again replaced " with \" Used Newtonsoft Json and then it parsed successfully. See my answer.
Using This Site and your JsonString, Below are the proper Json Class Structure that I created.
public class Appliance
{
public string name { get; set; }
public Json json { get; set; }
public string id { get; set; }
public string sphereId { get; set; }
public string createdAt { get; set; }
public string updatedAt { get; set; }
}
public class OnHomeEnter
{
public int state { get; set; }
public int delay { get; set; }
public int fadeTime { get; set; }
public bool active { get; set; }
public long updatedAt { get; set; }
}
public class OnHomeExit
{
public int state { get; set; }
public int delay { get; set; }
public int fadeTime { get; set; }
public bool active { get; set; }
public long updatedAt { get; set; }
}
public class OnRoomEnter
{
public int state { get; set; }
public int delay { get; set; }
public int fadeTime { get; set; }
public bool active { get; set; }
public int updatedAt { get; set; }
}
public class OnRoomExit
{
public int state { get; set; }
public int delay { get; set; }
public int fadeTime { get; set; }
public bool active { get; set; }
public int updatedAt { get; set; }
}
public class OnNear
{
public int state { get; set; }
public int delay { get; set; }
public int fadeTime { get; set; }
public bool active { get; set; }
public long updatedAt { get; set; }
}
public class OnAway
{
public int state { get; set; }
public int delay { get; set; }
public int fadeTime { get; set; }
public bool active { get; set; }
public long updatedAt { get; set; }
}
public class Json
{
public OnHomeEnter onHomeEnter { get; set; }
public OnHomeExit onHomeExit { get; set; }
public OnRoomEnter onRoomEnter { get; set; }
public OnRoomExit onRoomExit { get; set; }
public OnNear onNear { get; set; }
public OnAway onAway { get; set; }
}
Once Done, I used Json.Net
to Parse the JsonString to Appliance Object
Below is the Final Json String and Parser.
"[{\"name\":\"Beeldscherm\",\"json\":{\"onHomeEnter\":{\"state\":0,\"delay\":0,\"fadeTime\":0,\"active\":false,\"updatedAt\":1487166732440},\"onHomeExit\":{\"state\":0,\"delay\":120,\"fadeTime\":0,\"active\":false,\"updatedAt\":1487163669388},\"onRoomEnter\":{\"state\":1,\"delay\":0,\"fadeTime\":0,\"active\":false,\"updatedAt\":1},\"onRoomExit\":{\"state\":0,\"delay\":120,\"fadeTime\":0,\"active\":false,\"updatedAt\":1},\"onNear\":{\"state\":1,\"delay\":0,\"fadeTime\":0,\"active\":false,\"updatedAt\":1487164911729},\"onAway\":{\"state\":0,\"delay\":2,\"fadeTime\":0,\"active\":false,\"updatedAt\":1487164909184}},\"id\":\"58a44fa04f40b016004ffca2\",\"sphereId\":\"58a44c0a4f40b016004ffc9d\",\"createdAt\":\"2017 - 02 - 15T13: 52:12.783Z\",\"updatedAt\":\"2017 - 02 - 15T12: 55:05.332Z\"}]";
And Below is how I was able to successfully Parse Json.
List<Appliance> appJson = JsonConvert.DeserializeObject<List<Appliance>>(JsonData);
Good Luck.

Related

Not getting object data from Json deserialization

I am getting Json data from a web server, but when I try to deserialize it to objects, I am not getting any data. The Json string looks like this:
{"success":true,"data":[{"Id":6,"CustomerGuid":"70b390d8-82d5-4bba-aa68-fc8268a1b1ff","UserName":"victoria_victoria#nopCommerce.com","Email":"victoria_victoria#nopCommerce.com","CustomerRoles":[{"Id":3,"Name":"Registered","SystemName":"Registered"}],"AdminComment":null,"IsTaxExempt":false,"AffiliateId":0,"VendorId":0,"HasShoppingCartItems":false,"Active":false,"Deleted":false,"IsSystemAccount":false,"SystemName":null,"LastIpAddress":null,"CreatedOnUtc":"\/Date(1472933472393)\/","LastLoginDateUtc":null,"LastActivityDateUtc":"\/Date(1472933472393)\/","ExternalAuthenticationRecords":[],"ShoppingCartItems":[]},{"Id":5,"CustomerGuid":"eb9e6f24-f362-4c10-942a-366e2919dc11","UserName":"brenda_lindgren#nopCommerce.com","Email":"brenda_lindgren#nopCommerce.com","CustomerRoles":[{"Id":3,"Name":"Registered","SystemName":"Registered"}],"AdminComment":null,"IsTaxExempt":false,"AffiliateId":0,"VendorId":0,"HasShoppingCartItems":false,"Active":false,"Deleted":false,"IsSystemAccount":false,"SystemName":null,"LastIpAddress":null,"CreatedOnUtc":"\/Date(1472933472363)\/","LastLoginDateUtc":null,"LastActivityDateUtc":"\/Date(1472933472363)\/","ExternalAuthenticationRecords":[],"ShoppingCartItems":[]},{"Id":4,"CustomerGuid":"9f46dbae-6942-410c-90b8-9b38a0890064","UserName":"james_pan#nopCommerce.com","Email":"james_pan#nopCommerce.com","CustomerRoles":[{"Id":3,"Name":"Registered","SystemName":"Registered"}],"AdminComment":null,"IsTaxExempt":false,"AffiliateId":0,"VendorId":0,"HasShoppingCartItems":false,"Active":false,"Deleted":false,"IsSystemAccount":false,"SystemName":null,"LastIpAddress":null,"CreatedOnUtc":"\/Date(1472933472317)\/","LastLoginDateUtc":null,"LastActivityDateUtc":"\/Date(1472933472317)\/","ExternalAuthenticationRecords":[],"ShoppingCartItems":[]},{"Id":3,"CustomerGuid":"6277386b-13ee-427b-9cfe-4ebfa487c340","UserName":"arthur_holmes#nopCommerce.com","Email":"arthur_holmes#nopCommerce.com","CustomerRoles":[{"Id":3,"Name":"Registered","SystemName":"Registered"}],"AdminComment":null,"IsTaxExempt":false,"AffiliateId":0,"VendorId":0,"HasShoppingCartItems":false,"Active":false,"Deleted":false,"IsSystemAccount":false,"SystemName":null,"LastIpAddress":null,"CreatedOnUtc":"\/Date(1472933472253)\/","LastLoginDateUtc":null,"LastActivityDateUtc":"\/Date(1472933472253)\/","ExternalAuthenticationRecords":[],"ShoppingCartItems":[]},{"Id":2,"CustomerGuid":"241f45f1-b38c-4e22-8c5a-743fa3276620","UserName":"steve_gates#nopCommerce.com","Email":"steve_gates#nopCommerce.com","CustomerRoles":[{"Id":3,"Name":"Registered","SystemName":"Registered"}],"AdminComment":null,"IsTaxExempt":false,"AffiliateId":0,"VendorId":0,"HasShoppingCartItems":false,"Active":false,"Deleted":false,"IsSystemAccount":false,"SystemName":null,"LastIpAddress":null,"CreatedOnUtc":"\/Date(1472933472207)\/","LastLoginDateUtc":null,"LastActivityDateUtc":"\/Date(1472933472207)\/","ExternalAuthenticationRecords":[],"ShoppingCartItems":[]},{"Id":1,"CustomerGuid":"a940dc03-5f52-47d2-9391-8597b3b31cf2","UserName":"tony#lakesideos.com","Email":"tony#lakesideos.com","CustomerRoles":[{"Id":1,"Name":"Administrators","SystemName":"Administrators"},{"Id":2,"Name":"Forum Moderators","SystemName":"ForumModerators"},{"Id":3,"Name":"Registered","SystemName":"Registered"}],"AdminComment":null,"IsTaxExempt":false,"AffiliateId":0,"VendorId":0,"HasShoppingCartItems":true,"Active":true,"Deleted":false,"IsSystemAccount":false,"SystemName":null,"LastIpAddress":"71.185.255.7","CreatedOnUtc":"\/Date(1472933470783)\/","LastLoginDateUtc":"\/Date(1477522483903)\/","LastActivityDateUtc":"\/Date(1477523996553)\/","ExternalAuthenticationRecords":[],"ShoppingCartItems":[{"Id":1,"StoreId":1,"ShoppingCartTypeId":1,"CustomerId":1,"ProductId":18,"AttributesXml":null,"CustomerEnteredPrice":0.0000,"Quantity":1,"CreatedOnUtc":"\/Date(1473801903447)\/","UpdatedOnUtc":"\/Date(1473803336207)\/","IsFreeShipping":false,"IsShipEnabled":true,"AdditionalShippingCharge":0.0000,"IsTaxExempt":false}]}]}
I created these classes from the recommendation given in this link:
recommendation
I used this to create the classes: json2csharp
Response class:
class Response
{
bool success;
IList<Customer> data;
}
Customer class:
class Customer
{
public int Id { get; set; }
public string CustomerGuid { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public List<CustomerRole> CustomerRoles { get; set; }
public object AdminComment { get; set; }
public bool IsTaxExempt { get; set; }
public int AffiliateId { get; set; }
public int VendorId { get; set; }
public bool HasShoppingCartItems { get; set; }
public bool Active { get; set; }
public bool Deleted { get; set; }
public bool IsSystemAccount { get; set; }
public object SystemName { get; set; }
public string LastIpAddress { get; set; }
public DateTime CreatedOnUtc { get; set; }
public DateTime? LastLoginDateUtc { get; set; }
public DateTime LastActivityDateUtc { get; set; }
public List<object> ExternalAuthenticationRecords { get; set; }
public List<object> ShoppingCartItems { get; set; }
}
CustomerRole class:
class CustomerRole
{
public int Id { get; set; }
public string Name { get; set; }
public string SystemName { get; set; }
}
ExternalAuthenticationRecord class:
class ExternalAuthenticationRecord
{
public int Id { get; set; }
public int CustomerId { get; set; }
public string Email { get; set; }
public object ExternalIdentifier { get; set; }
public object ExternalDisplayIdentifier { get; set; }
public object OAuthToken { get; set; }
public object OAuthAccessToken { get; set; }
public string ProviderSystemName { get; set; }
}
ShoppingCartItem class:
class ShoppingCartItem
{
public int Id { get; set; }
public int StoreId { get; set; }
public int ShoppingCartTypeId { get; set; }
public int CustomerId { get; set; }
public int ProductId { get; set; }
public object AttributesXml { get; set; }
public double CustomerEnteredPrice { get; set; }
public int Quantity { get; set; }
public DateTime CreatedOnUtc { get; set; }
public DateTime UpdatedOnUtc { get; set; }
public bool IsFreeShipping { get; set; }
public bool IsShipEnabled { get; set; }
public double AdditionalShippingCharge { get; set; }
public bool IsTaxExempt { get; set; }
}
I am using this statement to deserialzie the Json string: Response res = (Response)JsonConvert.DeserializeObject(customerJson, (typeof(Response)));
When I stop it in the debugger, it shows "res" as data: null and success: false.
I am not getting any errors. It is just not giving me the data from the Json string.
Any help that anybody can provide to figure out why I'm not getting the data I want in "res", would be gratefully appreciated.
Thanks,
Tony
The problem is related to the accessibility level in your Response class. By default the fields, property and method are private so JsonConvert is not able to fill the properties.
Change the class as follow:
class Response
{
public bool success {get; set;}
public IList<Customer> data {get; set;}
}
And it wil works.
Another improvement is related to the JsonConvert use. To avoid the explicit cast use this type conversion: JsonConvert.DeserializeObject<T>(string) where T will be Response

Deserialize JSON to C# Object - No Data being deserialized

Found an odd issue when trying to deserialize a JSON string into a C# Object. It "seems" to perform the operation successfully (as in it does not throw any exception etc), however the outputted POCO contains does not contain any data from the JSON string, it only contains type default data (nulls,"", 0 etc). I have tried this process with other JSON and it works fine.
private string GetJson()
{
return #"{""backdrop_path"":"" / 1LrtAhWPSEetJLjblXvnaYtl7eA.jpg"",""created_by"":[{""id"":488,""name"":""Steven Spielberg"",""profile_path"":"" / pOK15UNaw75Bzj7BQO1ulehbPPm.jpg""},{""id"":31,""name"":""Tom Hanks"",""profile_path"":"" / a14CNByTYALAPSGlwlmfHILpEIW.jpg""}],""episode_run_time"":[60],""first_air_date"":""2001 - 09 - 09"",""genres"":[{""id"":28,""name"":""Action""},{""id"":12,""name"":""Adventure""},{""id"":18,""name"":""Drama""},{""id"":10752,""name"":""War""}],""homepage"":""http://www.hbo.com/band-of-brothers"",""id"":4613,""in_production"":false,""languages"":[""de"",""fr"",""lt"",""nl"",""en""],""last_air_date"":""2001-11-04"",""name"":""Band of Brothers"",""networks"":[{""id"":49,""name"":""HBO""}],""number_of_episodes"":10,""number_of_seasons"":1,""origin_country"":[""GB"",""US""],""original_language"":""en"",""original_name"":""Band of Brothers"",""overview"":""Drawn from interviews with survivors of Easy Company, as well as their journals and letters, Band of Brothers chronicles the experiences of these men from paratrooper training in Georgia through the end of the war. As an elite rifle company parachuting into Normandy early on D-Day morning, participants in the Battle of the Bulge, and witness to the horrors of war, the men of Easy knew extraordinary bravery and extraordinary fear - and became the stuff of legend. Based on Stephen E. Ambrose's acclaimed book of the same name."",""popularity"":3.435181,""poster_path"":""/bUrt6oeXd04ImEwQjO9oLjRguaA.jpg"",""production_companies"":[{""name"":""DreamWorks SKG"",""id"":27},{""name"":""HBO Films"",""id"":7429},{""name"":""DreamWorks Television"",""id"":15258}],""seasons"":[{""air_date"":null,""episode_count"":4,""id"":14071,""poster_path"":""/bMN9iiSAdnmAjflREfCCH0TTNyQ.jpg"",""season_number"":0},{""air_date"":""2001-09-09"",""episode_count"":10,""id"":14070,""poster_path"":""/15SN18OVbYt12Wzttclh51Sz9m1.jpg"",""season_number"":1}],""status"":""Ended"",""type"":""Scripted"",""vote_average"":8.5,""vote_count"":47}";
}
[TestMethod]
public void DeserializeTmdbShowData_ValidShowData_ReturnDeserializedObject()
{
//Arrange
string jsonStream = GetJson();
JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
//Act
var tmdbShowDetails = jsonSerializer.Deserialize<List<TmdbShowDetailsDto>>(jsonStream);
//Assert
Assert.IsNotNull(tmdbShowDetails);
Assert.IsNotNull(tmdbShowDetails.First().backdrop_path);
}
public class TmdbShowDetailsDto
{
public string backdrop_path { get; set; }
public Created_By[] created_by { get; set; }
public int[] episode_run_time { get; set; }
public string first_air_date { get; set; }
public Genre[] genres { get; set; }
public string homepage { get; set; }
public int id { get; set; }
public bool in_production { get; set; }
public string[] languages { get; set; }
public string last_air_date { get; set; }
public string name { get; set; }
public Network[] networks { get; set; }
public int number_of_episodes { get; set; }
public int number_of_seasons { get; set; }
public string[] origin_country { get; set; }
public string original_language { get; set; }
public string original_name { get; set; }
public string overview { get; set; }
public float popularity { get; set; }
public string poster_path { get; set; }
public Production_Companies[] production_companies { get; set; }
public Season[] seasons { get; set; }
public string status { get; set; }
public string type { get; set; }
public float vote_average { get; set; }
public int vote_count { get; set; }
}
public class Created_By
{
public int id { get; set; }
public string name { get; set; }
public string profile_path { get; set; }
}
public class Genre
{
public int id { get; set; }
public string name { get; set; }
}
public class Network
{
public int id { get; set; }
public string name { get; set; }
}
public class Production_Companies
{
public string name { get; set; }
public int id { get; set; }
}
public class Season
{
public string air_date { get; set; }
public int episode_count { get; set; }
public int id { get; set; }
public string poster_path { get; set; }
public int season_number { get; set; }
}
Any ideas - Im sure I have missed something glaringly obvious but I cannot see it. Using .NET 4.5
Help appreciated.
Cheers
I used http://json2csharp.com/, and the code is like this, so you should look at it.
public class Poster
{
public string full { get; set; }
public string medium { get; set; }
public string thumb { get; set; }
}
public class Fanart
{
public string full { get; set; }
public string medium { get; set; }
public string thumb { get; set; }
}
public class Images
{
public Poster poster { get; set; }
public Fanart fanart { get; set; }
}
public class Ids
{
public int trakt { get; set; }
public string slug { get; set; }
public int tvdb { get; set; }
public string imdb { get; set; }
public int tmdb { get; set; }
public int tvrage { get; set; }
}
public class Show
{
public string title { get; set; }
public string overview { get; set; }
public int year { get; set; }
public string status { get; set; }
public Images images { get; set; }
public Ids ids { get; set; }
}
public class Poster2
{
public string full { get; set; }
public string medium { get; set; }
public string thumb { get; set; }
}
public class Fanart2
{
public string full { get; set; }
public string medium { get; set; }
public string thumb { get; set; }
}
public class Images2
{
public Poster2 poster { get; set; }
public Fanart2 fanart { get; set; }
}
public class Ids2
{
public int trakt { get; set; }
public string slug { get; set; }
public string imdb { get; set; }
public int tmdb { get; set; }
}
public class Movie
{
public string title { get; set; }
public string overview { get; set; }
public int year { get; set; }
public Images2 images { get; set; }
public Ids2 ids { get; set; }
}
public class Headshot
{
public object full { get; set; }
public object medium { get; set; }
public object thumb { get; set; }
}
public class Images3
{
public Headshot headshot { get; set; }
}
public class Ids3
{
public int trakt { get; set; }
public string slug { get; set; }
public string imdb { get; set; }
public int tmdb { get; set; }
public int tvrage { get; set; }
}
public class Person
{
public string name { get; set; }
public Images3 images { get; set; }
public Ids3 ids { get; set; }
}
public class RootObject
{
public string type { get; set; }
public object score { get; set; }
public Show show { get; set; }
public Movie movie { get; set; }
public Person person { get; set; }
}
You can use Paste-Special Feature in your VS-IDE Paster JSON as Classes
public class Rootobject
{
public Class1[] Property1 { get; set; }
}
public class Class1
{
public string type { get; set; }
public object score { get; set; }
public Show show { get; set; }
public Movie movie { get; set; }
public Person person { get; set; }
}
public class Show
{
public string title { get; set; }
public string overview { get; set; }
public int year { get; set; }
public string status { get; set; }
public Images images { get; set; }
public Ids ids { get; set; }
}
public class Images
{
public Poster poster { get; set; }
public Fanart fanart { get; set; }
}
public class Poster
{
public string full { get; set; }
public string medium { get; set; }
public string thumb { get; set; }
}
public class Fanart
{
public string full { get; set; }
public string medium { get; set; }
public string thumb { get; set; }
}
public class Ids
{
public int trakt { get; set; }
public string slug { get; set; }
public int tvdb { get; set; }
public string imdb { get; set; }
public int tmdb { get; set; }
public int tvrage { get; set; }
}
public class Movie
{
public string title { get; set; }
public string overview { get; set; }
public int year { get; set; }
public Images1 images { get; set; }
public Ids1 ids { get; set; }
}
public class Images1
{
public Poster1 poster { get; set; }
public Fanart1 fanart { get; set; }
}
public class Poster1
{
public string full { get; set; }
public string medium { get; set; }
public string thumb { get; set; }
}
public class Fanart1
{
public string full { get; set; }
public string medium { get; set; }
public string thumb { get; set; }
}
public class Ids1
{
public int trakt { get; set; }
public string slug { get; set; }
public string imdb { get; set; }
public int tmdb { get; set; }
}
public class Person
{
public string name { get; set; }
public Images2 images { get; set; }
public Ids2 ids { get; set; }
}
public class Images2
{
public Headshot headshot { get; set; }
}
public class Headshot
{
public object full { get; set; }
public object medium { get; set; }
public object thumb { get; set; }
}
public class Ids2
{
public int trakt { get; set; }
public string slug { get; set; }
public string imdb { get; set; }
public int tmdb { get; set; }
public int tvrage { get; set; }
}
Look like you JSON string is not in correct format that you are trying to deserialize. For example i have not find show property in the C# class but it present in JSON.
So this issue I couldn't figure out in the night or early in the morning - it took me till this afternoon until I realised that I was had the wrong JSON!!, so no wonder it wasn't working! I got mixed up with a few different apis that provided JSON. Thanks to those who had pointed out that the class looks wrong, made me double check my code and realise the simplicity of this issue. Kinda needed some rubber ducking to spot the problem. Cheers

C# Json Deserialization fails

I'm trying to make an application that can show local TV guide trough JSON rest api C #, but has some problems with deserialization of my Json response.
i'm only intresest in the array NOW in my json call and i do not own the api service.
I get this error message:
An exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.DLL but was not handled in user code
Additional information: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[TDC_Play_TV_Mobil.superclass2+Now]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'now', line 1, position 7.
My function:
private HttpClient client;
public async Task<List<superclass2.Now>> GetComments()
{
client = new HttpClient();
var response = await client.GetAsync(new Uri("http://api.yousee.tv/rest/tvguide/nowandnext/"));
if (response.IsSuccessStatusCode)
{
string json = await response.Content.ReadAsStringAsync();
System.Diagnostics.Debug.WriteLine(json);
var task = Task.Factory.StartNew(() => JsonConvert.DeserializeObject<List<superclass2.Now>>(json));
var value = await task;
// List<superclass2.Now> comments = Newtonsoft.Json.JsonConvert.DeserializeObject<List<superclass2.Now>>(await json);
System.Diagnostics.Debug.WriteLine("Comments er lavet");
return value;
}
else
{
throw new Exception("Errorhandling message");
}
}
My class file:
public class superclass2
{
public class Logos
{
public string small { get; set; }
public string large { get; set; }
public string small_seapp { get; set; }
public string large_seapp { get; set; }
public string extralarge { get; set; }
public string super { get; set; }
public string mega { get; set; }
public string netgem { get; set; }
public string svg { get; set; }
}
public class ChannelInfo
{
public string name { get; set; }
public string shortname { get; set; }
public string logo_image_prefix { get; set; }
public Logos logos { get; set; }
public int archivedays { get; set; }
public string channelcolor { get; set; }
}
public class FormattedDate
{
public string time_begin { get; set; }
public string time_end { get; set; }
public string date { get; set; }
}
public class ImagesSixteenbynine
{
public string large { get; set; }
public string medium { get; set; }
public string small { get; set; }
}
public class ImagesFourbythree
{
public string large { get; set; }
public string small { get; set; }
}
public class ImagesSquare
{
public string large { get; set; }
public string medium { get; set; }
public string small { get; set; }
}
public class Now
{
public int id { get; set; }
public int dvb_id { get; set; }
public int channel { get; set; }
public ChannelInfo channel_info { get; set; }
public string orgtitle { get; set; }
public string cast { get; set; }
public string directors { get; set; }
public string series_info { get; set; }
public int series_id { get; set; }
public string series_name { get; set; }
public bool allowseriesrecording { get; set; }
public int totalinarchive { get; set; }
public int popularity_score { get; set; }
public int totalupcoming { get; set; }
public int category { get; set; }
public int subcategory { get; set; }
public string category_string { get; set; }
public string subcategory_string { get; set; }
public int begin { get; set; }
public object actual_begin { get; set; }
public int end { get; set; }
public int actual_end { get; set; }
public int tvdate { get; set; }
public FormattedDate formatted_date { get; set; }
public string title { get; set; }
public string description { get; set; }
public bool archive { get; set; }
public bool scrubbingallowed { get; set; }
public int expiresfromarchive { get; set; }
public bool startover { get; set; }
public string imageprefix { get; set; }
public ImagesSixteenbynine images_sixteenbynine { get; set; }
public ImagesFourbythree images_fourbythree { get; set; }
public ImagesSquare images_square { get; set; }
public List<object> decorations { get; set; }
}
public class Logos2
{
public string small { get; set; }
public string large { get; set; }
public string small_seapp { get; set; }
public string large_seapp { get; set; }
public string extralarge { get; set; }
public string super { get; set; }
public string mega { get; set; }
public string netgem { get; set; }
public string svg { get; set; }
}
public class ChannelInfo2
{
public string name { get; set; }
public string shortname { get; set; }
public string logo_image_prefix { get; set; }
public Logos2 logos { get; set; }
public int archivedays { get; set; }
public string channelcolor { get; set; }
}
public class FormattedDate2
{
public string time_begin { get; set; }
public string time_end { get; set; }
public string date { get; set; }
}
public class ImagesSixteenbynine2
{
public string large { get; set; }
public string medium { get; set; }
public string small { get; set; }
}
public class ImagesFourbythree2
{
public string large { get; set; }
public string small { get; set; }
}
public class ImagesSquare2
{
public string large { get; set; }
public string medium { get; set; }
public string small { get; set; }
}
public class Next
{
public int id { get; set; }
public int dvb_id { get; set; }
public int channel { get; set; }
public ChannelInfo2 channel_info { get; set; }
public string orgtitle { get; set; }
public string cast { get; set; }
public string directors { get; set; }
public string series_info { get; set; }
public int series_id { get; set; }
public string series_name { get; set; }
public bool allowseriesrecording { get; set; }
public int totalinarchive { get; set; }
public int popularity_score { get; set; }
public int totalupcoming { get; set; }
public int category { get; set; }
public int subcategory { get; set; }
public string category_string { get; set; }
public string subcategory_string { get; set; }
public int begin { get; set; }
public int actual_begin { get; set; }
public int end { get; set; }
public int actual_end { get; set; }
public int tvdate { get; set; }
public FormattedDate2 formatted_date { get; set; }
public string title { get; set; }
public string description { get; set; }
public bool archive { get; set; }
public bool scrubbingallowed { get; set; }
public int expiresfromarchive { get; set; }
public bool startover { get; set; }
public string imageprefix { get; set; }
public ImagesSixteenbynine2 images_sixteenbynine { get; set; }
public ImagesFourbythree2 images_fourbythree { get; set; }
public ImagesSquare2 images_square { get; set; }
public List<object> decorations { get; set; }
}
public class RootObject
{
public List<Now> now { get; set; }
public List<Next> next { get; set; }
}
}
Your JSON isn't a List<superclass2.Now>, it's a superclass2.RootObject. So you need to do something like:
public async Task<List<superclass2.Now>> GetComments()
{
client = new HttpClient();
var response = await client.GetAsync(new Uri("http://api.yousee.tv/rest/tvguide/nowandnext/"));
if (response.IsSuccessStatusCode)
{
string json = await response.Content.ReadAsStringAsync();
System.Diagnostics.Debug.WriteLine(json);
var task = Task.Factory.StartNew(() => JsonConvert.DeserializeObject<superclass2.RootObject>(json));
var value = await task;
System.Diagnostics.Debug.WriteLine("Comments er lavet");
return (value == null ? null : value.now);
}
else
{
throw new Exception("Errorhandling message");
}
}
Agree with Jon Skeet it would be nicer to eliminate the nesting of classes, purely for improved readability. If you need these classes to exist only in a specific scope, it is better to use nested namespaces. They aren't causing your bug, however.

deserializing an object with a generic list

I am trying to deserialize an object, the type is populated but I am getting null for the List<Sport>. Any ideas?
My classes:
class Sports
{
public MsgTypes type { get; set; }
public List<Sport> Sport { get; set; }
}
class Sport
{
public int Id { get; set; }
public int Import_id { get; set; }
public string Name { get; set; }
public int Active { get; set; }
public int Order { get; set; }
public int Min_bet { get; set; }
public int Max_bet { get; set; }
public int Updated { get; set; }
public string Feed_type { get; set; }
public string Locale { get; set; }
}
The command for deserialization:
Sports _sports = (Sports) JsonConvert.DeserializeObject<Sports>(jsonObj);
This is my JSON object:
"{\"code\":0,\"type\":4,\"Sports\":[{\"Sport\":{\"id\":\"1\",\"import_id\":\"1\",\"name\":\"Soccer\",\"active\":true,\"order\":\"1\",\"min_bet\":\"0\",\"max_bet\":\"0\",\"updated\":\"1403194889\",\"feed_type\":\"Betradar\",\"locale\":\"en_us\"}},{\"Sport\":{\"id\":\"2\",\"import_id\":\"5\",\"name\":\"Tennis\",\"active\":true,\"order\":\"3\",\"min_bet\":\"0\",\"max_bet\":\"0\",\"updated\":\"1403194771\",\"feed_type\":\"Betradar\",\"locale\":\"en_us\"}},{\"Sport\":{\"id\":\"3\",\"import_id\":\"6\",\"name\":\"Handball\",\"active\":true,\"order\":\"6\",\"min_bet\":\"0\",\"max_bet\":\"0\",\"updated\":\"1403152901\",\"feed_type\":\"Betradar\",\"locale\":\"en_us\"}},{\"Sport\":{\"id\":\"4\",\"import_id\":\"4\",\"name\":\"Ice Hockey\",\"active\":true,\"order\":\"4\",\"min_bet\":\"0\",\"max_bet\":\"0\",\"updated\":\"1403080245\",\"feed_type\":\"Betradar\",\"locale\":\"en_us\"}},{\"Sport\":{\"id\":\"7\",\"import_id\":\"2\",\"name\":\"Basketball\",\"active\":true,\"order\":\"2\",\"min_bet\":\"0\",\"max_bet\":\"0\",\"updated\":\"1403194830\",\"feed_type\":\"Betradar\",\"locale\":\"en_us\"}},{\"Sport\":{\"id\":\"8\",\"import_id\":\"23\",\"name\":\"Volleyball\",\"active\":true,\"order\":\"5\",\"min_bet\":\"0\",\"max_bet\":\"0\",\"updated\":\"1403194591\",\"feed_type\":\"Betradar\",\"locale\":\"en_us\"}},{\"Sport\":{\"id\":\"9\",\"import_id\":\"12\",\"name\":\"Rugby\",\"active\":true,\"order\":\"7\",\"min_bet\":\"0\",\"max_bet\":\"0\",\"updated\":\"1403194710\",\"feed_type\":\"Betradar\",\"locale\":\"en_us\"}},{\"Sport\":{\"id\":\"12\",\"import_id\":\"11\",\"name\":\"Motorsport\",\"active\":true,\"order\":\"12\",\"min_bet\":\"0\",\"max_bet\":\"0\",\"updated\":\"1403065699\",\"feed_type\":\"Betradar\",\"locale\":\"en_us\"}},{\"Sport\":{\"id\":\"13\",\"import_id\":\"3\",\"name\":\"Baseball\",\"active\":true,\"order\":\"13\",\"min_bet\":\"0\",\"max_bet\":\"0\",\"updated\":\"1403194834\",\"feed_type\":\"Betradar\",\"locale\":\"en_us\"}},{\"Sport\":{\"id\":\"14\",\"import_id\":\"16\",\"name\":\"American Football\",\"active\":true,\"order\":\"14\",\"min_bet\":\"0\",\"max_bet\":\"0\",\"updated\":\"1403143326\",\"feed_type\":\"Betradar\",\"locale\":\"en_us\"}},{\"Sport\":{\"id\":\"16\",\"import_id\":\"34\",\"name\":\"Beach Volley\",\"active\":true,\"order\":\"16\",\"min_bet\":\"0\",\"max_bet\":\"0\",\"updated\":\"1403194417\",\"feed_type\":\"Betradar\",\"locale\":\"en_us\"}}]}"
You need one more level of nesting and different class names. You should be able to deserialize to such structure:
class SportsParent
{
//Code for MsgTypes was not provided so it is commented out
public List<SportGroup> Sports { get; set; }
}
class SportGroup
{
public SportItem Sport { get; set; }
}
class SportItem
{
public int Id { get; set; }
public int Import_id { get; set; }
public string Name { get; set; }
public bool Active { get; set; } //need to be converted to bool instead of int
public int Order { get; set; }
public int Min_bet { get; set; }
public int Max_bet { get; set; }
public int Updated { get; set; }
public string Feed_type { get; set; }
public string Locale { get; set; }
}
You can deserialize using such code:
SportsParent _sports = JsonConvert.DeserializeObject<SportsParent>(jsonObj);

JSONConvert.DeserializeObject not handling child array with unnamed array items

I have the following JSON object coming to me from a web service
{
"room":{
"name":"Thunderdome",
"created_at":"2012/04/15 00:36:27 +0000",
"id":xxxxxxx,
"users":[
{
"type":"Member",
"avatar_url":"url",
"created_at":"2012/02/27 14:11:57 +0000",
"id":1139474,
"email_address":"xxx#xxxxxxx.com",
"admin":false,
"name":"xxxx xxxxx"
},
{
"type":"Member",
etc
I'm using the following line to deserialize:
var room = JsonConvert.DeserializeObject<SingleRoom>(text);
And the following mapping classes
public class SingleRoom
{
public Room Room { get; set; }
}
[DataContract]
public class Room
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
public string Image {
get { return "Assets/campfire.png"; }
}
[DataMember]
public string Topic { get; set; }
[DataMember(Name ="membership_limit")]
public int MembershipLimit { get; set; }
[DataMember]
public bool Full { get; set; }
[DataMember]
public bool Locked { get; set; }
[DataMember(Name = "open_to_guests")]
public bool OpenToGuests { get; set; }
[DataMember(Name = "updated_at")]
public DateTime UpdatedAt { get; set; }
[DataMember(Name = "created_at")]
public DateTime CreatedAt { get; set; }
[DataMember(Name = "active_token_value")]
public string ActiveTokenValue { get; set; }
[DataMember(Name = "Users")]
public List<User> Users { get; set; }
}
[DataContract]
public class User
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember(Name = "email_address")]
public string EmailAddress { get; set; }
[DataMember]
public bool Admin { get; set; }
[DataMember]
public DateTime CreatedAt { get; set; }
[DataMember]
public string Type { get; set; }
[DataMember(Name = "avatar_url")]
public string AvatarUrl { get; set; }
}
The 'Room' object deserializes correctly but the Users property on the Room is always null. I know that a null result is the result of a JSON.NET serialization that couldn't find the matching property. However, I think I have it right? List should match to user. I know the array object users in the JSON doesn't have named children, is that the issue? If so, how do I solve it?
Thanks!
This works.... You can rename them (or use JsonProperty attribute) to use c# style property names
(BTW: Json.Net doesn't require DataMember, DataContract attributes)
var obj = JsonConvert.DeserializeObject<SingleRoom>(json)
public class User
{
public string type { get; set; }
public string avatar_url { get; set; }
public string email_address { get; set; }
public bool admin { get; set; }
public string name { get; set; }
public string created_at { get; set; }
public int id { get; set; }
}
public class Room
{
public string topic { get; set; }
public int membership_limit { get; set; }
public bool locked { get; set; }
public string name { get; set; }
public List<User> users { get; set; }
public bool full { get; set; }
public bool open_to_guests { get; set; }
public string updated_at { get; set; }
public string created_at { get; set; }
public int id { get; set; }
}
public class SingleRoom
{
public Room room { get; set; }
}
PS: You may find that site useful http://json2csharp.com/ .
In my case, I had missing to add the "public" key for the child property.

Categories