Deserialize JSON string to C# classes Deserialize JSON string to C# classes json json

Deserialize JSON string to C# classes


The sample data provided describes an array (tubeStatusRootObject[]) but when you try to deserialize you cast it to a single instance which is an invalid cast. that is why data is null.

Also no need to re-invent the wheel if there are tools available to simply the problem.

static http = new HttpClient(); //reuse httpclient instead of creating a new one each time.public async static Task<tubeStatusRootObject[]> GetTubeStatus(string url) {    var response = await http.GetAsync(url);     var json = await response.Content.ReadAsStringAsync(); //This is working    var data = Newtonsoft.Json.JsonConvert.DeserializeObject<tubeStatusRootObject[]>(json);    return data;}


It's a bit complicated object that you are getting.

When It's deserialized(the way you're doing now), it looks out for matching names of objects with same datatype as expected. If it does not find, deserialization fails and returns null. And it's pretty sure.

If not newtonsoft, you can either match the datatype of each nested object to some generic. Or need to perform some string operations to deserialize it yourself(Pretty complicated).

I would prefer using Newtonsoft.json for such objects


As others have said, you need to deserialize into an array, not just a single instance of the type you've defined as the response is an array.

If you read the response into a string then Json.Net means you only need a single line response

var data= Newtonsoft.Json.JsonConvert.DeserializeObject<tubeStatusRootObject[]>(result);

this is compared with 3+lines when using DataContractJsonSerializer

var deserializer = new DataContractJsonSerializer(typeof(tubeStatusRootObject[]));using (var ms = new MemoryStream(Encoding.UTF8.GetBytes(result))){    var data = (tubeStatusRootObject[])deserializer.ReadObject(ms);}

(Note the use of the using wrapper to ensure the MemoryStream is disposed.)

If you read the HTTP response stream directly into the deserializer you don't get the LoC saving though.

using (var s = http.GetStreamAsync(url).Result)using (var sr = new StreamReader(s))using (var reader = new Newtonsoft.Json.JsonTextReader(sr)){    var serializer = new Newtonsoft.Json.JsonSerializer();    var data = serializer.Deserialize<tubeStatusRootObject[]>(reader);}

Versus

using (var stream = await response.Content.ReadAsStreamAsync()){    var dcjs = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(tubeStatusRootObject[]));    var data= (tubeStatusRootObject[])dcjs.ReadObject(stream);}

The other thing you may want to consider is performance. Json.Net claim the following

Json Serializers performance comparison graph