Reputation: 657
I have a json document, that constantly increases the list of discriminators. My problem is that I can't get the "UnknownDerivedTypeHandling" to work. System.Text.Json and .net9.
// https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/polymorphism
[JsonPolymorphic(TypeDiscriminatorPropertyName = "$type", UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)]
[JsonDerivedType(typeof(RecordClass))]
[JsonDerivedType(typeof(RecordProfileClass), typeDiscriminator: "profile")]
[JsonDerivedType(typeof(RecordAccountClass), typeDiscriminator: "account")]
public class RecordClass
{
[JsonPropertyName("$type")]
public string RecordType { get; set; } = string.Empty;
[JsonPropertyName("createdAt"), JsonRequired]
public DateTime Created { get; set; }
}
public class RecordProfileClass : RecordClass
{
[JsonPropertyName("description")]
public string Description { get; set; } = string.Empty;
[JsonPropertyName("displayName"), JsonRequired]
public string DisplayName { get; set; } = string.Empty;
}
public class RecordAccountClass : RecordClass
{
[JsonPropertyName("userprincipalname"), JsonRequired]
public string UserPrincipalName{ get; set; } = string.Empty;
[JsonPropertyName("objectId"), JsonRequired]
public Guid ObjectId { get; set; } = Guid.Empty;
}
When I recieve json document and a "not listed" discriminator is used, the deserialization failes with the error:
System.Text.Json.JsonException: 'Read unrecognized type discriminator id 'guest'. Path: ...
What I was hoping for, was being able to fall back to base type if an unknown discriminator appeared with JsonUnknownDerivedTypeHandling.FallBackToBaseType
I have read Microsoft's page How to serialize properties of derived classes with System.Text.Json a several times, but I still don't get what I am doing wrong.
My JsonSerializerOptions
JsonSerializerOptions jsonOptions = new JsonSerializerOptions()
{
RespectNullableAnnotations = true,
WriteIndented = true
};
JsonSerializer.Deserialize<MessageClass>(messageJson, jsonOptions);
The MessageClass is a root class containing messageid, time, identities who "did the act", etc. My code:
public class MessageClass
{
[JsonPropertyName("did"), JsonRequired]
public string Did { get; set; } = string.Empty;
[JsonPropertyName("time_us"), JsonRequired]
public long Time_US { get; set; } = 0;
[JsonPropertyName("commit")]
public CommitClass? Commit { get; set; } = null;
// There is more, but not relevant...
}
public class CommitClass
{
[JsonPropertyName("rev"), JsonRequired]
public string Rev { get; set; } = string.Empty;
[JsonPropertyName("operation"), JsonRequired]
public string Operation { get; set; } = string.Empty;
// There is more, but not relevant...
// THE BASE CLASS
[JsonPropertyName("record")]
public RecordClass? Record { get; set; }
}
I apologize if the code is messy, but it has been through a tennis match of a debugging session. And not all the editing of the code I did before writing this issue has been well thought out.
Upvotes: 2
Views: 132
Reputation: 143098
JsonPolymorphicAttribute.UnknownDerivedTypeHandling
is for serialization (as the corresponding enum). From the docs:
Gets or sets the behavior when serializing an undeclared derived runtime type.
You can use the JsonPolymorphicAttribute.IgnoreUnrecognizedTypeDiscriminators
setting:
[JsonPolymorphic(TypeDiscriminatorPropertyName = "$type",
UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType,
IgnoreUnrecognizedTypeDiscriminators = true)]
Upvotes: 2