-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Description
Description
Minimal APIs uses the runtime type to call the serializer in most of the scenarios, that means once I have a compiler generated type (unspeakable type) returning from my API, this type will be used for serialization.
While it works correctly when the reflection-based resolver is turned on, I could not find a way to add this compiler generated type to my source-generated JsonSerializerContext. Even if I try to specify the interface implemented by type, eg.: IAsyncEnumerable and still getting the following error:
Metadata for type 'Program+<<<Main>$>g__Foo|0_5>d' was not provided by TypeInfoResolver of type 'MyContext'. If using source generation, ensure that all root types passed to the serializer have been indicated with 'JsonSerializableAttribute', along with any types that might be serialized polymorphically.
Reproduction Steps
var builder = WebApplication.CreateBuilder(args);
builder.Services.ConfigureHttpJsonOptions(options => options.SerializerOptions.TypeInfoResolver = MyContext.Default);
var app = builder.Build();
app.MapGet("/foo", Foo);
async IAsyncEnumerable<int> Foo()
{
foreach (var i in Enumerable.Range(0, 10))
{
await Task.Delay(1000);
yield return i;
}
}
[JsonSerializable(typeof(IAsyncEnumerable<int>))]
internal partial class MyContext : JsonSerializerContext
{}Expected behavior
While is possible to have some additional logic on ASP.NET Core side, to check some sort of known types, the expected behavior is to have the metadata resolution be able to detect, as a fallback in the source generator context, if the requested type implements one of the interfaces registered in the context.
Eg.:
Current source-gen`ed context
public override global::System.Text.Json.Serialization.Metadata.JsonTypeInfo? GetTypeInfo(global::System.Type type)
{
if (type == typeof(global::System.Collections.Generic.IAsyncEnumerable<global::System.Int32>))
{
return this.IAsyncEnumerableInt32;
}
return null;
}Expected
public override global::System.Text.Json.Serialization.Metadata.JsonTypeInfo? GetTypeInfo(global::System.Type type)
{
if (type == typeof(global::System.Collections.Generic.IAsyncEnumerable<global::System.Int32>))
{
return this.IAsyncEnumerableInt32;
}
if (type.IsAssignableFrom(typeof(global::System.Collections.Generic.IAsyncEnumerable<global::System.Int32>)))
{
return this.IAsyncEnumerableInt32;
}
return null;
}Actual behavior
System.NotSupportedException: Metadata for type 'Program+<<<Main>$>g__Foo|0_5>d' was not provided by TypeInfoResolver of type 'MyContext'. If using source generation, ensure that all root types passed to the serializer have been indicated with 'JsonSerializableAttribute', along with any types that might be serialized polymorphically.
at System.Text.Json.ThrowHelper.ThrowNotSupportedException_NoMetadataForType(Type type, IJsonTypeInfoResolver resolver)
at System.Text.Json.JsonSerializerOptions.GetTypeInfoInternal(Type type, Boolean ensureConfigured, Boolean resolveIfMutable)
at Microsoft.AspNetCore.Internal.ExecuteHandlerHelper.WriteJsonResponseAsync[T](HttpResponse response, T value, JsonSerializerOptions options, JsonTypeInfo`1 jsonTypeInfo)
at lambda_method4(Closure, Object, HttpContext)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)
Regression?
No response
Known Workarounds
No response
Configuration
No response
Other information
No response