I'm not sure how Foo
or Bar
is determined in your code, but for now let's assume you have a JSON structure like this:
var json = @"
{
isFoo: true,
item: {}
}";
In which case Foo
or Bar
is determined by isFoo
.
FooOrBar
class could be subjective. I would not define class like that, but use polymorphism:
interface IItem
{
bool IsFoo { get; }
}
class Foo : IItem
{
public bool IsFoo => true;
}
class Bar : IItem
{
public bool IsFoo => false;
}
[JsonConverter(typeof(CustomJsonConverter))]
class MyClass
{
public IItem Item { get; set; }
}
I set CustomJsonConverter
to MyClass
because of the JSON structure I have. I need to use information available in the parent object of item
to determine Foo
or Bar
so I have to set JsonConverter
to the declaring type of Item
property. If you use information available in item
property, you can move converter to the Item
property.
Now implement CustomJsonConverter
like this:
class CustomJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => true;
public override object ReadJson(JsonReader reader, Type objectType,
object existingValue, JsonSerializer serializer)
{
var token = JToken.ReadFrom(reader);
if (token.Type == JTokenType.Null)
{
return null;
}
// Create an instance of MyClass, and set property as per "isFoo".
var obj = new MyClass();
if (token["isFoo"].Value<bool>())
{
obj.Item = new Foo();
}
else
{
obj.Item = new Bar();
}
// Populate properties
serializer.Populate(token.CreateReader(), obj);
return obj;
}
public override void WriteJson(JsonWriter writer, object value,
JsonSerializer serializer)
{
throw new NotSupportedException();
}
}