Accessing the JSON type discriminator in the deserialized type #110817
-
I want to access the type discriminator used in polymorphic JSON deserialization in the deserialized type. However, it appears that it is either not possible or not conventional The following code runs without errors (sharplab) using System.Text.Json;
using System.Text.Json.Serialization;
_ = JsonSerializer.Deserialize<M>("""{"S": "Z"}""");
[JsonPolymorphic(TypeDiscriminatorPropertyName = "S")]
[JsonDerivedType(typeof(Z), "Z")]
abstract class M {
}
class Z : M; However, by adding a property on abstract class M {
public required string S { get; set; }
} the code now fails with the following exception (sharplab) System.Text.Json.JsonException: JSON deserialization for type 'Z' was missing required properties including: 'S'.
at System.Text.Json.ThrowHelper.ThrowJsonException_JsonRequiredPropertyMissing(JsonTypeInfo parent, BitArray requiredPropertiesSet)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.OnTryReadAsObject(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, Object& value)
at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value)
at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader& reader, Type typeToConvert, JsonSerializerOptions options, ReadStack& state, T& value, Boolean& isPopulatedValue)
at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader& reader, T& value, JsonSerializerOptions options, ReadStack& state)
at System.Text.Json.Serialization.Metadata.JsonTypeInfo`1.Deserialize(Utf8JsonReader& reader, ReadStack& state)
at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 utf8Json, JsonTypeInfo`1 jsonTypeInfo, Nullable`1 actualByteCount)
at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1 json, JsonTypeInfo`1 jsonTypeInfo)
at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
at Program.<Main>$(String[] args)
at System.RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
at System.Reflection.MethodBaseInvoker.InvokeDirectByRefWithFewArgs(Object obj, Span`1 copyOfArgs, BindingFlags invokeAttr) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
There's been a few issues open on this. Having a physical property that corresponds to metadata properties (like type discriminator) is not currently supported. We originally wanted to do the same thing as you. For a while we just fell back to an abstract get-only property that was json ignored that all subclasses must implement. We eventually dropped that approach and just used type checks as the actual value of the discriminator was unimportant to us (as long as we could differentiate objects of the base type we were happy) |
Beta Was this translation helpful? Give feedback.
There's been a few issues open on this. Having a physical property that corresponds to metadata properties (like type discriminator) is not currently supported.
We originally wanted to do the same thing as you. For a while we just fell back to an abstract get-only property that was json ignored that all subclasses must implement. We eventually dropped that approach and just used type checks as the actual value of the discriminator was unimportant to us (as long as we could differentiate objects of the base type we were happy)