KEMBAR78
Add source gen support for `unspeakable types` · Issue #82457 · dotnet/runtime · GitHub
Skip to content

Add source gen support for unspeakable types #82457

@brunolins16

Description

@brunolins16

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

Metadata

Metadata

Labels

area-System.Text.Jsonpartner-impactThis issue impacts a partner who needs to be kept updatedsource-generatorIndicates an issue with a source generator feature

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions