Description
In both the RDF and RDG we have code like the following:
aspnetcore/src/Shared/RouteHandlers/ExecuteHandlerHelper.cs
Lines 36 to 53 in 0b10e13
This doesn't work with the unspeakable types behavior that was added to System.Text.Json - dotnet/runtime#83631. In particular, GetTypeInfo(runtimeType)
doesn't work when using unspeakable types.
We started using the "runtimeType" back in .NET Core 3.0 (bed3542) when we switched from Json.Net to System.Text.Json and wanted to maintain the polymorphic serialization behavior of Json.Net (ex. if the "declared type" was a base type, and the endpoint returned a derived type, we want to serialize all the derived properties). This strategy was adopted by Minimal APIs as well, when they were introduced.
This approach was then changed early in .NET 8 in order to support "System.Text.Json Polymorphism" features that were added in .NET 7. (See #45405). The strategy used by that PR was: "when a JsonPolymorphismOptions
is detected, uses the declared type's JsonTypeInfo to call the serializer." When it isn't detected, use the "runtimeType"'s JsonTypeInfo
to maintain the above polymorphic serialization behavior to not break backwards compatibility.
In order to support all these scenarios, we need to tweak our JSON serialization strategy. After consulting with @brunolins16 and @eiriktsarpalis, the strategy we have settled on is:
- When a
JsonPolymorphismOptions
is detected (or when polymorphism is not possible - ex. ValueType, sealed, etc), use the declared type'sJsonTypeInfo
to call the serializer.- This is no change to what we do today in .NET 8.
- When the above rule doesn't work, instead of using the "runtimeType", we will serialize the value "as object" - i.e.
JsonSerializer.Serialize<object>(value, options)
.- This will allow System.Text.Json to control the behavior of serialization. It will allow to fix issues like:
- "unspeakable type support" Add source gen support for
unspeakable types
runtime#82457 - Polymorphic Type Resolving System.Text.Json Polymorphic Type Resolving Issue runtime#77532
- Along with keeping the above behavior consistent with Json.Net before .NET Core 3.0.
- "unspeakable type support" Add source gen support for
- This will allow System.Text.Json to control the behavior of serialization. It will allow to fix issues like:
A drawback to this strategy is that JsonSerializer.Serialize<object>(value, options)
is not guaranteed to be trim/AOT-compatible, and thus it is annotated as incompatible. We will need to suppress these warnings in ASP.NET, which is OK because of the other mechanisms we are adding to support trimming/AOT - dotnet/runtime#83279.
However, we can't do this until the JSON Trimming feature switch is merged, or we will regress the AOT size and warnings. We may also need to wait for System.Text.Json Polymorphic Type Resolving Issue.