Replies: 7 comments
-
I tried running the reproduction and it seems to be working as expected, i.e. the discriminator
Hope this helps. |
Beta Was this translation helpful? Give feedback.
-
How should I deserialize into the MetaLifecycleEvent class? EventBase is the base class for all events, MetaEvent is a broad category of events, with MetaLifecycleEvent belonging to the MetaEvent class, which in turn belongs to EventBase. |
Beta Was this translation helpful? Give feedback.
-
I think that when serializing/deserializing, if a subclass specified, it should check whether the subclass has the |
Beta Was this translation helpful? Give feedback.
-
You would need to add a
That might work when using reflection-based serialization, but it might not be possible using the source generator which needs to know the entire hierarchy at compile time. Therefore, it is not supported (though there are ways to achieve this via contract customization). |
Beta Was this translation helpful? Give feedback.
-
I don't need AOT. Could you help me write a simple example using custom contracts for my sample data? I'm not very familiar with it. Also, I hope STJ can find a way to support AOT in the future. |
Beta Was this translation helpful? Give feedback.
-
I attempted to use DefaultJsonTypeInfoResolver to override the behavior of GetTypeInfo for subtype recognition. However, serialization isn't correct. I suspect this is because the TypeDiscriminatorPropertyName returned by DerivedTypesResolver.GetTypeInfo is unique. During serialization, only one TypeDiscriminatorPropertyName can be obtained, resulting in the serialization of only one TypePropertyName. Therefore, I believe there is room for improvement here. JsonPolymorphismOptions could be changed to List. This would allow for the presence of multiple JsonPolymorphismOptions during serialization, enabling the addition of multiple type attribute fields. I think this improvement shouldn't be difficult to implement. using OneBotNet.Test;
using System.Text.Encodings.Web;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.Json.Serialization.Metadata;
var jsonSerializerOptions = new JsonSerializerOptions
{
TypeInfoResolver = new DerivedTypesResolver(),
AllowOutOfOrderMetadataProperties = true
};
var triangle = new Derived2(3);
var output = JsonSerializer.Serialize<BaseClass>(triangle, jsonSerializerOptions);
Console.WriteLine(output); // {"type2":"Derived2","Data2":3}
var jsonText = """
{"type1":"Derived1","type2":"Derived2","Data2":123}
""";
var baseClass = JsonSerializer.Deserialize<BaseClass>(jsonText, jsonSerializerOptions);
Console.WriteLine(baseClass); // Derived2 { Data2 = 123 }
public sealed class DerivedTypesResolver : DefaultJsonTypeInfoResolver
{
public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options)
{
var baseInfo = base.GetTypeInfo(type, options);
if (baseInfo.PolymorphismOptions is not { DerivedTypes: { } baseInfoTypes })
return baseInfo;
foreach (var derived in baseInfoTypes.ToArray())
HandleType(derived, options, baseInfo.PolymorphismOptions, baseInfoTypes);
return baseInfo;
}
private void HandleType(JsonDerivedType nextType, JsonSerializerOptions options, JsonPolymorphismOptions? polymorphismOptions, IList<JsonDerivedType> baseInfoTypes)
{
if (nextType.DerivedType.IsAbstract)
baseInfoTypes.Remove(nextType);
else if (!baseInfoTypes.Contains(nextType))
baseInfoTypes.Add(nextType);
var baseInfo = GetTypeInfo(nextType.DerivedType, options);
if (baseInfo is not { PolymorphismOptions: { } derived })
return;
if (polymorphismOptions != null && baseInfo.PolymorphismOptions != null && baseInfo.PolymorphismOptions.TypeDiscriminatorPropertyName != null)
{
polymorphismOptions.TypeDiscriminatorPropertyName = baseInfo.PolymorphismOptions.TypeDiscriminatorPropertyName;
}
foreach (var next in derived.DerivedTypes)
HandleType(next, options, baseInfo.PolymorphismOptions, baseInfoTypes);
}
}
[JsonPolymorphic(TypeDiscriminatorPropertyName = "type1")]
[JsonDerivedType(typeof(Derived1), nameof(Derived1))]
abstract record BaseClass;
[JsonPolymorphic(TypeDiscriminatorPropertyName = "type2")]
[JsonDerivedType(typeof(Derived2), nameof(Derived2))]
abstract record Derived1 : BaseClass;
record Derived2(int Data2) : Derived1; |
Beta Was this translation helpful? Give feedback.
-
Here's the code I'm referencing:#81236 |
Beta Was this translation helpful? Give feedback.
-
Description
System.Text.Json Polymorphism Type Discriminator Does Not Support Subtypes Class Polymorphism
System.Text.Json Version
Test
Beta Was this translation helpful? Give feedback.
All reactions