-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Description
Description
In order to solve polymorphic JSON serialization scenarios in ASP.NET, specifically in ASP.NET's EndpointFilterDelegate which uses object as the "declared type", we need to serialize the value "as object". However, this doesn't work with source generation by default unless the user explicitly adds typeof(object) to the source generated context.
Reproduction Steps
Run:
using System.Text.Json;
using System.Text.Json.Serialization;
var value = new Derived() { BaseString = "Base", DerivedString = "Derived" };
var options = new JsonSerializerOptions();
options.TypeInfoResolver = new TestJsonContext();
Console.WriteLine(JsonSerializer.Serialize<object>(value, options));
internal class Base
{
public string? BaseString { get; set; }
}
internal class Derived : Base
{
public string? DerivedString { get; set; }
}
[JsonSerializable(typeof(Base))]
[JsonSerializable(typeof(Derived))]
internal partial class TestJsonContext : JsonSerializerContext { }Expected behavior
Should output
{"DerivedString":"Derived","BaseString":"Base"}
Actual behavior
System.NotSupportedException
Message=JsonTypeInfo metadata for type 'System.Object' was not provided by TypeInfoResolver of type 'TestJsonContext'. If using source generation, ensure that all root types passed to the serializer have been annotated with 'JsonSerializableAttribute', along with any types that might be serialized polymorphically.
StackTrace:
at System.Text.Json.ThrowHelper.ThrowNotSupportedException_NoMetadataForType(Type type, IJsonTypeInfoResolver resolver) in /_/src/libraries/System.Text.Json/src/System/Text/Json/ThrowHelper.Serialization.cs:line 726
at System.Text.Json.JsonSerializerOptions.GetTypeInfoInternal(Type type, Boolean ensureConfigured, Boolean resolveIfMutable, Boolean fallBackToNearestAncestorType) in /_/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Caching.cs:line 90
at System.Text.Json.JsonSerializerOptions.get_ObjectTypeInfo() in /_/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializerOptions.Caching.cs:line 144
at System.Text.Json.JsonSerializer.GetTypeInfo[T](JsonSerializerOptions options) in /_/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Helpers.cs:line 54
at System.Text.Json.JsonSerializer.Serialize[TValue](TValue value, JsonSerializerOptions options) in /_/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/JsonSerializer.Write.String.cs:line 32
at Program.<Main>$(String[] args) in C:\DotNetTest\Net8Console\Program.cs:line 9
Regression?
No response
Known Workarounds
A workaround is to add
[JsonSerializable(typeof(object))]To the TestJsonContext.
Configuration
No response
Other information
One concern is that we shouldn't regress the Native AOT size by too much by fixing this problem. Our current goal is to have a ~10 MB native executable for the dotnet new api -aot template. Fixing this issue can't take up too much of that 10 MB goal. We should measure and ensure we aren't adding too much size to fix this (for example by rooting a bunch of converters that are not necessary).