Skip to content

ASP.NET Core Web API (Native AOT) project fail to serialize the object to JSON #59659

Closed
@Scythemen

Description

@Scythemen

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

Environment:
Visual Studio Community 2022 17.12.3
Win10 + .NET SDK 8

I created an ASP.NET Core Web API (Native AOT) project in Visual Studio using .NET 8. The minimal API endpoints below worked as expected:

using System.Text.Json.Serialization;

namespace WebApplication1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateSlimBuilder(args);

            builder.Services.ConfigureHttpJsonOptions(options =>
            {
                options.SerializerOptions.TypeInfoResolverChain.Insert(0, AppJsonSerializerContext.Default);
            });

            var app = builder.Build();

            var sampleTodos = new Todo[] {
                new(1, "Walk the dog"),
                new(2, "Do the dishes", DateOnly.FromDateTime(DateTime.Now)),
                new(3, "Do the laundry", DateOnly.FromDateTime(DateTime.Now.AddDays(1))),
                new(4, "Clean the bathroom"),
                new(5, "Clean the car", DateOnly.FromDateTime(DateTime.Now.AddDays(2)))
            };

            var todosApi = app.MapGroup("/todos");
            todosApi.MapGet("/", () => sampleTodos);
            todosApi.MapGet("/{id}", (int id) =>
                sampleTodos.FirstOrDefault(a => a.Id == id) is { } todo
                    ? Results.Ok(todo)
                    : Results.NotFound());

            app.Run();
        }
    }

    public record Todo(int Id, string? Title, DateOnly? DueBy = null, bool IsComplete = false);

    [JsonSerializable(typeof(Todo[]))]
    internal partial class AppJsonSerializerContext : JsonSerializerContext
    {

    }
}

After moving the endpoints to TodosController.cs and configuring the JSON serializer in a separate file JsonTypeMetaData.cs, I encountered the following exception:

NotSupportedException: JsonTypeInfo metadata for type 'WebApplication1.Todo[]' was not provided by TypeInfoResolver of type '[]'. 
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.

TodosController.cs:

// TodosController.cs
using Microsoft.AspNetCore.Mvc;

namespace WebApplication1.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class TodosController : ControllerBase
    {
        private static readonly Todo[] sampleTodos = new Todo[] {
            new(1, "Walk the dog"),
            new(2, "Do the dishes", DateOnly.FromDateTime(DateTime.Now)),
            new(3, "Do the laundry", DateOnly.FromDateTime(DateTime.Now.AddDays(1))),
            new(4, "Clean the bathroom"),
            new(5, "Clean the car", DateOnly.FromDateTime(DateTime.Now.AddDays(2)))
        };

        [HttpGet]
        public IActionResult GetTodos()
        {
            return Ok(sampleTodos);
        }

        [HttpGet("{id}")]
        public IActionResult GetTodoById(int id)
        {
            var todo = sampleTodos.FirstOrDefault(a => a.Id == id);
            return todo is not null ? Ok(todo) : NotFound();
        }
    }
}

JsonTypeMetaData.cs:

// JsonTypeMetaData.cs

using System.Text.Json;
using System.Text.Json.Serialization;

namespace WebApplication1
{
    public static class JsonTypeMetaData
    {
        public static void ConfigureJsonTypeMetaDatas(this IServiceCollection services)
        {
            services.ConfigureHttpJsonOptions(options =>
            {
                options.SerializerOptions.TypeInfoResolverChain.Insert(0, TodoJsonSerializerContext.Default);
            });
        }
    }


    public record Todo(int Id, string? Title, DateOnly? DueBy = null, bool IsComplete = false);

    [JsonSerializable(typeof(Todo[]))]
    internal partial class TodoJsonSerializerContext : JsonSerializerContext
    {
    }

}

Program.cs:

namespace WebApplication1
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = WebApplication.CreateSlimBuilder(args);

            builder.Services.ConfigureJsonTypeMetaDatas();   //   JsonTypeMetaData.cs

            builder.Services.AddControllers();

            var app = builder.Build();

            app.MapControllers();

            app.Run();
        }
    }

}

WebApplication.csproj

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
    <InvariantGlobalization>true</InvariantGlobalization>
    <PublishAot>true</PublishAot>
  </PropertyGroup>

</Project>

I tried a similar solution (#59128), but it didn't work for me. Any help would be greatly appreciated.

Expected Behavior

No response

Steps To Reproduce

The mini project:
WebApplication1.zip

Exceptions (if any)

No response

.NET Version

dotnet 8.0.404

Anything else?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-mvcIncludes: MVC, Actions and Controllers, Localization, CORS, most templates

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions