Skip to content

Async minimal route handlers don't serialize child members #39856

Closed
@halter73

Description

@halter73

The issue is best demonstrated with code. The response bodies for each route handler are written as comments.

var app = WebApplication.Create(args);

app.MapGet("/", Parent () => new Child()); // { "c": "c", "p": "p" }

app.MapGet("/task", () => Task.FromResult<Parent>(new Child())); // { "p": "p" }
app.MapGet("/valuetask", ValueTask<Parent> () => new(new Child())); // { "p": "p" }

app.MapGet("/taskobj", () => Task.FromResult<object>(new Child())); // { "c": "c", "p": "p" }
app.MapGet("/valuetaskobj", ValueTask<object> () => new(new Child())); // { "c": "c", "p": "p" }

app.Run();

record Parent(string P = "p");
record Child(string C = "c") : Parent;

This shows an inconsistency in how returned objects are serialized in async methods that return a Task<Parent> or ValueTask<Parent> vs non-async methods that return Parent when the runtime type is a child type.

The non-async route handler has the right behavior because it results in a call to WriteAsJsonAsync<object>(...) instead of WriteAsJsonAsync<Parent>(...) which is what gets called in the async case. See https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-polymorphism

Metadata

Metadata

Assignees

Labels

bugThis issue describes a behavior which is not expected - a bug.old-area-web-frameworks-do-not-use*DEPRECATED* This label is deprecated in favor of the area-mvc and area-minimal labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions