I have a class structure I can Serialize and Deserialize no problem. I have demonstrated it below in a contrived example
[JsonDerivedType(typeof(Apple),typeDiscriminator: "apple")]
public abstract class Fruit
{
public Seed seed { get; }
protected Fruit(Seed seed)
{
this.seed = seed;
}
}
public sealed class Apple : Fruit
{
[JsonConstructor]
public Apple(Seed seed) : base(seed) { }
}
public sealed class AppleSeed : Seed
{
[JsonConstructor]
public AppleSeed() {}
}
[JsonDerivedType(typeof(AppleSeed),typeDiscriminator: "apple")]
public abstract class Seed { }
But I want the Apple constructor to require the type AppleSeed:
[JsonConstructor]
public Apple(AppleSeed seed) : base(seed) { }
This serializes fine but fails to deserialize since the deserializer needs the base class info. I attempted to use generics to fix this but couldn't work it out. Is there a reliable way to deserialize polymorphic parameters using System.Text.Json without implementing a custom deserializer? Thanks
The problem with your public Apple(AppleSeed seed) : base(seed) { }
constructor is explained in the documentation page Use immutable types and properties: Parameterized constructors:
The parameter names of a parameterized constructor must match the property names and types.
Since the constructor parameter type AppleSeed seed
does not match the property type Seed seed
, the constructor parameter cannot be used. Failing demo here.
The easiest workaround is to hide the base type property with a new
property of the same name and the required type:
public sealed class Apple : Fruit
{
[JsonConstructor]
public Apple(AppleSeed seed) : base(seed) { }
public new AppleSeed seed => (AppleSeed)base.seed;
}
See also:
Working fiddle here.