1

I'm using Newtonsoft JSON Converter to deserialize some JSON text, but I have a slight problem, this is that sometimes I get an array of objects returned to me from a web service, and other times it's just a single object, let me give you an example of what I mean:

{ "T":{ "S":"054", "T":"8", "D":"548" } } 

One is an array whereas the other is just a single object.

{ "T":[ { "S":"054", "T":"8", "D":"548" }, { "S":"054", "T":"8", "D":"548" }, { "S":"054", "T":"8", "D":"548" } ] } 

When I try to deserialize this using Newtonsoft, I get an error because it's expecting an array and sometimes receives only a single object, is there a way to get around this?

2 Answers 2

2

You can check the type of you first property like this :

JObject obj = JObject.Parse(json); if (obj["T"] is JArray) { // hit on second case } else { // hit on first case } 

After that's, you can deserialize you object on List<T> or T.

Hope it's help !

EDIT : With your pastebin classes, I have rebuild them and add a Callback on OnDeserialized :

class JSONResponse { public Line ROOT; } class Line { [JsonProperty("Time")] public Timestamp Time { get; set; } [JsonProperty("S")] public List<Station> S { get; set; } } class Timestamp { [JsonProperty("@TimeStamp")] public string @TimeStamp { get; set; } } class Station { [JsonProperty("@Code")] public string @Code { get; set; } [JsonProperty("@N")] public string @N { get; set; } [JsonProperty("P")] public List<Platform> P { get; set; } } class Platform { [JsonProperty("@N")] public string @N { get; set; } [JsonProperty("@Code")] public string @Code { get; set; } [JsonProperty("T")] public JToken T { get; set; } [OnDeserialized] internal void OnDeserializedMethod(StreamingContext context) { if (this.T != null) { if (this.T is JArray) { this.Trains = JsonConvert.DeserializeObject<List<Train>>(this.T.ToString()); } else { Train t = JsonConvert.DeserializeObject<Train>(this.T.ToString()); this.Trains = new List<Train>() { t }; } } } public List<Train> Trains; } class Train { [JsonProperty("@S")] public string @S { get; set; } [JsonProperty("@T")] public string @T { get; set; } [JsonProperty("@D")] public string @D { get; set; } [JsonProperty("@C")] public string @C { get; set; } [JsonProperty("@L")] public string @L { get; set; } [JsonProperty("@DE")] public string @DE { get; set; } } 

You will got your trains, on the Platform.Trains property

Sign up to request clarification or add additional context in comments.

5 Comments

The JSON I've posted is a very simple node took from the real JSON which can be found here: pastebin.com/A6qfFFS7 The '@T' nodes are the ones which can be either arrays or objects, so the same JSON stream has both, how do I go about this?
How do you deserialize your JSON ? With C# classes and JsonConvert.DeserializeObject<>() ?
Yep. JSONResponse centralLine = JsonConvert.DeserializeObject<JSONResponse>(JsonConvert.SerializeXmlNode(doc));
Could you post JSONResponse class ?
I add a callback on your models and update them :) Let me know if it's good now !
0

If you only wish you have one object type to deserialize to, one option would be to transform the JSON to an array if it is only a single element -- prior to attempting to deserialize. e.g.

// If only a single element, the JSON will not contain an opening bracket. if (!str.Contains('[')) { var index = str.IndexOf("{",1); // Ignore first brace. var lastIndex = str.LastIndexOf('}'); // Find last brace. str = str.Substring(0,index-1) + "[" + str.Substring(index, str.Length - index); // Insert bracket. str = str.Substring(0, lastIndex) + "]}"; // Insert bracket. } 

You could of course optimize the above to a single statement -- but this just gives you an idea of how you could manipulate the string prior to deserialization.

This also assumes you have no sub arrays inside of your JSON. Otherwise, you'll get false positives.

1 Comment

Unfortunately that won't work on this I believe: pastebin.com/A6qfFFS7 Thanks anyway!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.