How to add method description in Swagger UI in WebAPI Application

65,740

Solution 1

This is well documented in the project: https://github.com/domaindrivendev/Swashbuckle.AspNetCore#include-descriptions-from-xml-comments


Include Descriptions from XML Comments

To enhance the generated docs with human-friendly descriptions, you can annotate controller actions and models with Xml Comments and configure Swashbuckle to incorporate those comments into the outputted Swagger JSON:

1 - Open the Properties dialog for your project, click the "Build" tab and ensure that "XML documentation file" is checked. This will produce a file containing all XML comments at build-time.

At this point, any classes or methods that are NOT annotated with XML comments will trigger a build warning. To suppress this, enter the warning code "1591" into the "Suppress warnings" field in the properties dialog.

2 - Configure Swashbuckle to incorporate the XML comments on file into the generated Swagger JSON:

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1",
        new Info
        {
            Title = "My API - V1",
            Version = "v1"
        }
     );

     var filePath = Path.Combine(System.AppContext.BaseDirectory, "MyApi.xml");
     c.IncludeXmlComments(filePath);
}

3 - Annotate your actions with summary, remarks and response tags:

/// <summary>
/// Retrieves a specific product by unique id
/// </summary>
/// <remarks>Awesomeness!</remarks>
/// <response code="200">Product created</response>
/// <response code="400">Product has missing/invalid values</response>
/// <response code="500">Oops! Can't create your product right now</response>
[HttpGet("{id}")]
[ProducesResponseType(typeof(Product), 200)]
[ProducesResponseType(typeof(IDictionary<string, string>), 400)]
[ProducesResponseType(500)]
public Product GetById(int id)

4 - You can also annotate types with summary and example tags:

public class Product
{
    /// <summary>
    /// The name of the product
    /// </summary>
    /// <example>Men's basketball shoes</example>
    public string Name { get; set; }

    /// <summary>
    /// Quantity left in stock
    /// </summary>
    /// <example>10</example>
    public int AvailableStock { get; set; }
}

5 - Rebuild your project to update the XML Comments file and navigate to the Swagger JSON endpoint. Note how the descriptions are mapped onto corresponding Swagger fields.

NOTE: You can also provide Swagger Schema descriptions by annotating your API models and their properties with summary tags. If you have multiple XML comments files (e.g. separate libraries for controllers and models), you can invoke the IncludeXmlComments method multiple times and they will all be merged into the outputted Swagger JSON.


Following the instructions carefully you should get something that looks like:
https://swashbucklenetcore.azurewebsites.net/swagger/

Solution 2

For ASP.Net Core projects:

  1. install nuget package Swashbuckle.AspNetCore.Annotations

  2. Use SwaggerOperation attribute for a methods like [SwaggerOperation(Summary = "Write your summary here")]

  3. Enable annotations in Startup method ConfigureServices like the following:

    services.AddSwaggerGen(c =>
    {
        c.EnableAnnotations();
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
    });
    
  4. To exclude public method from appearing in swagger ui use attribute [ApiExplorerSettings(IgnoreApi = true)]. It is useful cause these methods can break swagger for some reason.

Launch project, go to localhost:[port number]/swagger and enjoy.

Solution 3

We use additional attributes to add required detail to the swagger documentation:

    [SwaggerOperationSummary("Add a new Pet to the store")]
    [SwaggerImplementationNotes("Adds a new pet using the properties supplied, returns a GUID reference for the pet created.")]
    [Route("pets")]
    [HttpPost]
    public async Task<IHttpActionResult> Post()
    {
        ...
    }

And then in you swagger config make sure to apply these filters:

config.EnableSwagger("swagger",
           c =>
           {
               c.OperationFilter<ApplySwaggerImplementationNotesFilterAttributes>();
               c.OperationFilter<ApplySwaggerOperationSummaryFilterAttributes>();

The code for the filters:

public class ApplySwaggerImplementationNotesFilterAttributes : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        var attr = apiDescription.GetControllerAndActionAttributes<SwaggerImplementationNotesAttribute>().FirstOrDefault();
        if (attr != null)
        {
            operation.description = attr.ImplementationNotes;
        }
    }
}

public class ApplySwaggerOperationSummaryFilterAttributes : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        var attr = apiDescription.GetControllerAndActionAttributes<SwaggerOperationSummaryAttribute>().FirstOrDefault();
        if (attr != null)
        {
            operation.summary = attr.OperationSummary;
        }
    }
}

Solution 4

For those who look for ability to expose custom localized controller names and action descriptions without shipping XML documents to customer and inventing yet another bunch of attrubutes:

    public static class SwaggerMiddlewareExtensions
    {
        private static readonly string[] DefaultSwaggerTags = new[]
        {
            Resources.SwaggerMiddlewareExtensions_DefaultSwaggerTag
        };

        public static void ConfigureSwagger(this IServiceCollection services)
        {
            services
                .AddSwaggerGen(options =>
                {
                    options.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo
                    {
                        Title = "My API",
                        Version = "v 1.0"
                    });

                    // your custom config

                    // this will group actions by localized name set in controller's DisplayAttribute
                    options.TagActionsBy(GetSwaggerTags);
                    
                    // this will add localized description to actions set in action's DisplayAttribute
                    options.OperationFilter<DisplayOperationFilter>();
                });
        }

        private static string[] GetSwaggerTags(ApiDescription description)
        {
            var actionDescriptor = description.ActionDescriptor as ControllerActionDescriptor;

            if (actionDescriptor == null)
            {
                return DefaultSwaggerTags;
            }

            var displayAttributes = actionDescriptor.ControllerTypeInfo.GetCustomAttributes(typeof(DisplayAttribute), false);

            if (displayAttributes == null || displayAttributes.Length == 0)
            {
                return new[]
                {
                    actionDescriptor.ControllerName
                };
            }

            var displayAttribute = (DisplayAttribute)displayAttributes[0];

            return new[]
            {
                displayAttribute.GetName()
            };
        }
    }

where DisplayOperationFilter is:

    internal class DisplayOperationFilter : IOperationFilter
    {
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var actionDescriptor = context.ApiDescription.ActionDescriptor as ControllerActionDescriptor;

            if (actionDescriptor == null)
            {
                return;
            }

            var displayAttributes = actionDescriptor.MethodInfo.GetCustomAttributes(typeof(DisplayAttribute), false);

            if (displayAttributes == null || displayAttributes.Length == 0)
            {
                return;
            }

            var displayAttribute = (DisplayAttribute)displayAttributes[0];

            operation.Description = displayAttribute.GetDescription();
        }
    }

Applicable for Swashbuckle 5.

Solution 5

A workaround is to add this to your .csproj file:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DocumentationFile>bin\Debug\netcoreapp1.1\FileXMLName.xml</DocumentationFile>
</PropertyGroup>
Share:
65,740
Lost
Author by

Lost

Updated on July 09, 2022

Comments

  • Lost
    Lost almost 2 years

    I am using Swagger as my API tooling framework and it is working out great so far. I just came across this page https://petstore.swagger.io/

    and saw how each method has a description. For example,

    POST: pet/ is described by add a new Pet to the store. I thought adding something like [Description("Description text")] should do it but it just does not. How can I achieve this?

  • Kenneth K.
    Kenneth K. over 5 years
    If you specify IncludeXmlComments in your Swagger config and enable the output in your project's properties, that is.
  • Lost
    Lost over 5 years
    Thank you for your answer. But nowhere on the page does it say that how does my MyApi.xml should look like?
  • Helder Sepulveda
    Helder Sepulveda over 5 years
  • Helder Sepulveda
    Helder Sepulveda over 5 years
    @WorkBee You really don't need to see how the XML should look like... that is automatically generated by VisualStudio from your annotations and swachbuckle knows how to read it... also the name MyApi.xml is just an example, you can name yours whatever you want, just need to keep it the same across your solution
  • Martin Florin
    Martin Florin over 5 years
    This is a really good description on how to work with Descriptions in Swagger and as @HelderSepulveda says the setting you do in step 1 is the one where you generate that XML file. You can also put any name there but make sure you use the same name in step 2 (described as MyApi.xml)
  • jet_choong
    jet_choong about 5 years
    This is exactly what I've been looking for the whole afternoon. To get my XML comments displays on Swagger UI query string's description, I checked the XML documentation file setting in project properties and added IncludeXmlComments(filepath). Thanks!
  • Dennis
    Dennis about 4 years
    I'm wondering, why this is not an accepted answer. XML docs is not a way to go. First of all, XML docs describes everything in .NET terms. Imagine, that your REST uses, say, ABAP developer. The second - what is the reason to distribute XML docs at all? The third - what if I want localized docs?
  • djsoteric
    djsoteric about 4 years
    No human is reading the XML doc itself. Why would that concern the ABAP developer? It's not accepted because the other question answers this in a native way with less code.
  • hossein andarkhora
    hossein andarkhora over 3 years
    tnx for your solution also my code has conflict with two using and it work with : [Swashbuckle.AspNetCore.Annotations.SwaggerOperation(Summary = "")]
  • fix
    fix over 3 years
    This is the outcome of doing this through project properties is Visual Studio. Right-click (your project) > Properties > Build > Output section > check "XML documentation file">
  • mathiash
    mathiash over 3 years
    I think this is the correct answer, this is what the OP expected to be able to do out-of-the box. This is just an additional package from the same developer as the original Swashbuckle.
  • Wouter Vanherck
    Wouter Vanherck about 3 years
    Don't forget to build (through properties) and reference c.IncludeXmlComments(filePath); the xml document in case you defined your models in another project / library
  • Aniyan Kolathur
    Aniyan Kolathur over 2 years
    I found something to do this in .net core from the following link, newbedev.com/…