-
Notifications
You must be signed in to change notification settings - Fork 10k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Stop Calling JSON GetTypeInfo with the runtime type #47548
Comments
If the polymorphism behavior is now cover inside STJ and the call to the
|
We will still have other calls to
|
I can take a look at this and also make sure that we emit the same invocations between RDF and RDG. Right now they are functionally the same, but syntactically different. |
@captainsafia - I can take this. I have a handful (3 maybe?) JSON changes in the works:
|
@eerhardt Awesome! Is it OK to put this in the preview4 milestone? |
Done. |
Calling GetTypeInfo with the object's runtime type doesn't work when using unspeakable types and using JSON source generation. There is no way to mark the unspeakable type (like a C# compiler implemented IAsyncEnumerable iterator) as JsonSerializable. Instead, when the "declared type"'s JsonTypeInfo isn't compatible with the runtime type w.r.t. polymorphism, serialize the value "as object", letting System.Text.Json's serialization take over to serialize the value. Fix dotnet#47548
* Stop Calling JSON GetTypeInfo with the runtime type Calling GetTypeInfo with the object's runtime type doesn't work when using unspeakable types and using JSON source generation. There is no way to mark the unspeakable type (like a C# compiler implemented IAsyncEnumerable iterator) as JsonSerializable. Instead, when the "declared type"'s JsonTypeInfo isn't compatible with the runtime type w.r.t. polymorphism, serialize the value "as object", letting System.Text.Json's serialization take over to serialize the value. Fix #47548 * Move RequestDelegateFactory tests to be shared with RDG * Add justifications for suppressing the warnings from JsonSerializer. * Convert RequestDelegateWritesAsJsonResponseBody_WithJsonSerializerContext to shared test between RDF and RDG. * Remove redundant JsonSerializerOptions. * Rename JsonTypeInfo extension method IsValid to ShouldUseWith.
dotnet/aspnetcore#47548 has now been fixed. Removing the workaround that was added for it.
dotnet/aspnetcore#47548 has now been fixed. Removing the workaround that was added for it.
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"'sJsonTypeInfo
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:
JsonPolymorphismOptions
is detected (or when polymorphism is not possible - ex. ValueType, sealed, etc), use the declared type'sJsonTypeInfo
to call the serializer.JsonSerializer.Serialize<object>(value, options)
.unspeakable types
runtime#82457A 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.
The text was updated successfully, but these errors were encountered: