Как добавить описание метода в Swagger UI в приложении WebAPI

Я использую Swagger в качестве своего инструментария API, и пока он работает отлично. Я только что наткнулся на эту страницу https://petstore.swagger.io/

и увидел, как у каждого метода есть описание. Например,

POST: pet/ описывается add a new Pet to the store, Я думал, добавив что-то вроде [Description("Description text")] должен сделать это, но это просто не так. Как мне этого добиться?

3 ответа

Решение

Это хорошо задокументировано в проекте: https://github.com/domaindrivendev/Swashbuckle.AspNetCore


Включить описания из комментариев XML

Чтобы дополнить сгенерированные документы понятными для человека описаниями, вы можете аннотировать действия и модели контроллера с помощью комментариев XML и настроить Swashbuckle для включения этих комментариев в выводимый Swagger JSON:

1. Откройте диалоговое окно "Свойства" для своего проекта, перейдите на вкладку "Сборка" и убедитесь, что установлен "XML документация". Это создаст файл, содержащий все комментарии XML во время сборки.

На этом этапе любые классы или методы, которые НЕ аннотированы XML-комментариями, вызовут предупреждение о сборке. Для подавления этого введите код предупреждения "1591" в поле "Подавить предупреждения" в диалоговом окне свойств.

2 - Настройте Swashbuckle для включения XML-комментариев к файлу в сгенерированный 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 - Аннотируйте свои действия с помощью резюме, замечаний и тегов ответа:

/// <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 - Вы также можете аннотировать типы с помощью тегов резюме и примера:

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 - Перестройте свой проект, чтобы обновить файл комментариев XML и перейти к конечной точке Swagger JSON. Обратите внимание, как описания отображаются в соответствующие поля Swagger.

ПРИМЕЧАНИЕ. Вы также можете предоставить описания схемы Swagger, добавив аннотации к своим моделям API и их свойствам. Если у вас есть несколько файлов комментариев XML (например, отдельные библиотеки для контроллеров и моделей), вы можете вызывать метод IncludeXmlComments несколько раз, и все они будут объединены в выходной Swagger JSON.


Внимательно следуя инструкциям, вы должны получить что-то похожее на:
https://swashbucklenetcore.azurewebsites.net/swagger/

Для проектов ASP.Net Core:

  1. установить пакет nuget Swashbuckle.AspNetCore.Annotations

  2. Используйте атрибут SwaggerOperation для таких методов, как [SwaggerOperation(Summary = "Write your summary here")]

  3. Включите аннотации в методе запуска ConfigureServices следующим образом:

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

    Запустите проект, перейдите на localhost:[номер порта]/swagger и наслаждайтесь.

Мы используем дополнительные атрибуты, чтобы добавить необходимые детали в документацию swagger:

    [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()
    {
        ...
    }

И тогда в вашей конфигурации swagger убедитесь, что применили эти фильтры:

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

Код для фильтров:

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;
        }
    }
}

Для тех, кто ищет возможность предоставлять настраиваемые локализованные имена контроллеров и описания действий без отправки XML-документов заказчику и придумывания еще одной кучи атрибутов:

    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()
            };
        }
    }

где DisplayOperationFilter является:

    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();
        }
    }

Применимо для Swashbuckle 5.

Обходной путь - добавить это в свой .csproj файл:

<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
    <DocumentationFile>bin\Debug\netcoreapp1.1\FileXMLName.xml</DocumentationFile>
</PropertyGroup>

Вы можете использовать комментарий для документации (3 слеша вместо стандартного 2), например:

/// <summary>
/// This is method summary I want displayed
/// </summary>
/// <param name="guid">guid as parameter</param>
/// <param name="page_number">Page number - defaults to 0</param>
/// <returns>List of objects returned</returns>
Другие вопросы по тегам