Swashbuckle.AspNetCore icon indicating copy to clipboard operation
Swashbuckle.AspNetCore copied to clipboard

Using [AsParameters] annotation in minimal api does not lift summary comments of the model

Open andreasuvoss opened this issue 1 year ago • 17 comments

Swashbuckle.AspNetCore: 6.5.0 .NET 7

I am not sure if this is a bug or a feature request.

When defining APIs using the minimal API approach, the summaries from models are not lifted from the XML documentation and put into the resulting swagger.json like I would expect. Before migrating to minimal API we used controllers, and the [FromQuery] annotation in a similar way. This gave the expected result. However [FromQuery] is not supported when using minimal API, instead the [AsParameters] annotation was added in .NET 7 .

The summaries are present in the XML file generated when building the project, but not in the swagger.json file.

I have created a minimal example showing that the summaries are not present (in both swagger.json or SwaggerUI) when using the [AsParameter] annotation, but they are included in the schema on the post request using the [FromBody] annotation.

I have a very ugly workaround using the WithOpenApi extension method from the NuGet package Microsoft.AspNetCore.OpenApi to add descriptions to the individual indices of each parameter by modifying the mapping from my minimal example like so:

app.MapGet("/AsParameters", ([AsParameters] AsParametersArgument request) => "Hello World!")
    .WithOpenApi(operation =>
    {
        operation.Parameters[0].Description = "Parameter one description";
        operation.Parameters[1].Description = "Parameter two description";
        return operation;
    });

Minimal example:

Project file:

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

    <PropertyGroup>
        <TargetFramework>net7.0</TargetFramework>
        <Nullable>enable</Nullable>
        <ImplicitUsings>enable</ImplicitUsings>
        <GenerateDocumentationFile>true</GenerateDocumentationFile>
        <NoWarn>1701;1702;1591</NoWarn>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
    </ItemGroup>

</Project>

Program.cs:

using System.Reflection;
using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
    var assemblyName = Assembly.GetExecutingAssembly().FullName?.Split(',')[0];
    options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"{assemblyName}.xml"));
});

var app = builder.Build();

app.MapGet("/AsParameters", ([AsParameters] AsParametersArgument request) => "Hello World!");

app.MapPost("/FromBody", ([FromBody] FromBodyArgument request) => "Hello World!");

app.UseSwagger();
app.UseSwaggerUI();

app.Run();

internal struct AsParametersArgument
{
    /// <summary>
    /// This is a property with the number one - This is nowhere in SwaggerUI
    /// </summary>
    public string PropertyOne { get; set; }

    /// <summary>
    /// This is a property with the number two - This is nowhere in SwaggerUI
    /// </summary>
    public string PropertyTwo { get; set; }
}

internal struct FromBodyArgument
{
    /// <summary>
    /// This is a property with the number eight (this description is present in Swagger)
    /// </summary>
    public string PropertyEight { get; set; }

    /// <summary>
    /// This is a property with the number nine (this description is present in Swagger)
    /// </summary>
    public string PropertyNine { get; set; }
}

andreasuvoss avatar May 31 '23 13:05 andreasuvoss