C#: Deserializing JSON when one field can be different types
c#, deserialization, json
Solution
With JSON.NET you could write a custom JSON converter. For example you could have the following objects:
public class Root
{
public string Status { get; set; }
public Result Result { get; set; }
}
public class Result
{
public bool? Value { get; set; }
public Item[] Items { get; set; }
}
public class Item
{
public string Name { get; set; }
public string UserIdentifier { get; set; }
public string MaxAccounts { get; set; }
}
and your JSON will be deserialized to a `Root[]`.
Here's how the custom JSON converter may look like:
public class ResultConverter: JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeof(Result);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Boolean)
{
return new Result
{
Value = (bool)reader.Value,
};
}
return new Result
{
Items = serializer.Deserialize<Item[]>(reader),
};
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
// If you want to support serializing you could implement this method as well
throw new NotImplementedException();
}
}
and then:
class Program
{
static void Main()
{
var json =
@"[
{
""status"": ""ok"",
""result"": true
},
{
""status"": ""ok"",
""result"": [
{
""name"": ""John Doe"",
""UserIdentifier"": ""abc"",
""MaxAccounts"": ""2""
}
]
}
]";
var settings = new JsonSerializerSettings();
settings.Converters.Add(new ResultConverter());
Root[] root = JsonConvert.DeserializeObject<Root[]>(json, settings);
// do something with the results here
}
}
Problem
I am communicating with an API that returns JSON containing either true, false or an array of string arrays. I wish to deserialize this JSON and store the boolean value, if there is one, in a class field called Success of data type bool, and the array, if there is one, in a field called Result of a custom data type. What is the best to go about achieving this? Some JSON: ``` [ {"status":"ok","result":true}, { "status":"ok", "result": [ {"name":"John Doe","UserIdentifier":"abc","MaxAccounts":"2"} ] } ] ``` My Result class: ``` class Result { string Name, string UserIdentifier, string MaxAccounts } ``` Class for communicating with the Api: ``` class Api { public string Status { get; set; } public Result[] Result { get; set; } public bool Success { get; set; } } ```