Skip to content

OpenAPI documentation is incorrect when using custom TryParse() binding with Minimal APIs #36412

@martincostello

Description

@martincostello

Describe the bug

If a type with a static TryParse() method is used as a parameter for a Minimal APIs action, the OpenAPI description does not work as would be expected.

There are two examples of this I have found for MapGet() and MapPost().

MapGet

If a parameter uses a custom type which has a TryParse() method, it will be reported as an object parameter, rather than the string that is received to be parsed.

image

MapPost

If a parameter uses a custom type which has a TryParse() method, it will be reported as both an object query string parameter and as the request body. If [FromBody] is used on the parameter, the extra parameter is not shown.

image

To Reproduce

Create an empty ASP.NET Core 6 project with a reference to Swashbuckle.AspNetCore with the below code as Program.cs.

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
    options.SwaggerDoc("v1", new() { Title = builder.Environment.ApplicationName, Version = "v1" });
});

var app = builder.Build();

// Will report a student as a query string parameter and as the request body
app.MapPost("/enroll1", (Student student) => Results.NoContent())
   .Accepts<Student>("application/json");

// Will report the student in the body only
app.MapPost("/enroll2", ([FromBody] Student student) => Results.NoContent())
   .Accepts<Student>("application/json");

// Will report the parameter as an object instead of as a string
app.MapGet("/student/{student}", (Student student) => $"Hi {student.Name}");

app.UseSwagger();
app.UseSwaggerUI(options =>
{
    options.EnableTryItOutByDefault();
    options.SwaggerEndpoint("/swagger/v1/swagger.json", $"{builder.Environment.ApplicationName} v1");
});

app.Run();

public record Student(string Name)
{
    public static bool TryParse(string value, out Student? result)
    {
        if (value is null)
        {
            result = null;
            return false;
        }

        result = new Student(value);
        return true;
    }
}

Further technical details

.NET SDK version 6.0.100-rc.1.21460.8

Metadata

Metadata

Assignees

Labels

Priority:1Work that is critical for the release, but we could probably ship withoutarea-minimalIncludes minimal APIs, endpoint filters, parameter binding, request delegate generator etcbugThis issue describes a behavior which is not expected - a bug.feature-minimal-actionsController-like actions for endpoint routingold-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

Relationships

None yet

Development

No branches or pull requests

Issue actions