Swagger response description not shown

Viewed 6260

I am currently attempting to display a description of a particular response in Swagger UI, but there doesn't seem to be a documentation that truly covers all aspects of that, and all the examples I've tried from Get started with Swashbuckle and ASP.NET Core don't work in .NET Core 3.1...

        /// <summary>
        /// Test route...
        /// </summary>
        /// <returns></returns>
        /// <response code="200">This is a test</response>
        [HttpGet]
        [ProducesResponseType(typeof(string), StatusCodes.Status200OK)]
        public IActionResult Get()
        {
            return Ok("Hello World");
        }

My .csproj contains the following as well:

  <PropertyGroup>
    <GenerateDocumentationFile>true</GenerateDocumentationFile>
    <NoWarn>$(NoWarn);1591</NoWarn>
  </PropertyGroup>

The Swagger UI ends up looking like this (and as you can see, the "Descriptipn" column doesn't contain the "This is a test" text as it probably should). Am I missing something?

Image preview

I also had added [SwaggerResponse(StatusCodes.Status200OK, ...)] to it, but nothing changes.

3 Answers

As it turns out, [SwaggerResponse] works properly, but before, I need to "enable annotations" in my Startup...

    services.AddSwaggerGen(config =>
    {
        config.SwaggerDoc("v1", new OpenApiInfo
        {
            Title = "Some API",
            Version = "v1"
        });

        config.EnableAnnotations();
    });

Since .NET v6 there're two ways of managing the API: classic API controllers and minimal API. They're quite different, so I provide two answers below.

For the classic/traditional API controllers

As per the official docs, it's done via XML comment with a combination of ProducesResponseType attribute:

<response code="201">This is a test</response>
[ProducesResponseType(StatusCodes.Status201Created)]

The comments need to be linked to Swagger

builder.Services.AddSwaggerGen(options =>
{
    // using System.Reflection;
    var xmlFilename = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
    options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, xmlFilename));
});

For the minimal API

Today, the minimal API is still quite raw with patchy support from both NSwag and Swashbuckle.

In this post on SO it's advised to use the old-school attributes:

app.MapGet("/clients",
    [SwaggerOperation(
        Summary = "returns clients",
        Description = "more description on get `clients`")]
    [SwaggerResponse(200, "success")]
    [SwaggerResponse(500, "some failure")]
    async (IClientRepository repo) =>
    {
        var results = await repo.GetClientsAsync();
        return mapper.Map<IEnumerable<ClientModel>>(results);
    }).WithTags("Clients");

In your project properties you should check Output XML documentation file found under the blade Build. Then in your startup file:

services.AddSwaggerGen(c =>
{
    //rest of your code

    //i'm using the default path generated, but you can adjust it as you want
    var XMLPath = AppDomain.CurrentDomain.BaseDirectory + nameof(MyNamespace) + ".xml";
    if (File.Exists(XMLPath))
    {
        c.IncludeXmlComments(XMLPath);
    }
});

If that still doesn't work check if the xml file appears in the bin folder. If not check the properties within Visual Studio and adjust Copy to output directory to Copy or Copy if newer.

Related