如何在 WebAPI 应用程序的 Swagger UI 中添加方法描述

How to add method description in Swagger UI in WebAPI Application

我正在使用 Swagger 作为我的 API 工具框架,到目前为止它运行良好。我刚看到这个页面 https://petstore.swagger.io/

并看到每个方法如何有描述。例如,

POST: pet/ 描述为 add a new Pet to the store。我认为添加类似 [Description("Description text")] 的内容应该可以,但事实并非如此。我怎样才能做到这一点?

您可以在文档中使用注释(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>

这在项目中有详细记录: https://github.com/domaindrivendev/Swashbuckle.AspNetCore#include-descriptions-from-xml-comments


包括来自 XML 条评论的描述

为了使用人性化的描述增强生成的文档,您可以使用 Xml Comments 注释控制器操作和模型,并配置 Swashbuckle 以将这些注释合并到输出的 Swagger JSON:

1 - 打开项目的“属性”对话框,单击 "Build" 选项卡并确保选中 "XML documentation file"。这将在构建时生成一个包含所有 XML 评论的文件。

此时,任何 类 或未使用 XML 注释注释的方法都将触发构建警告。要抑制这种情况,请在属性对话框的 "Suppress warnings" 字段中输入警告代码“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 Comments 文件并导航到 Swagger JSON 端点。请注意描述是如何映射到相应的 Swagger 字段的。

注意:您还可以通过使用摘要标签注释 API 模型及其属性来提供 Swagger 架构描述。如果您有多个 XML 评论文件(例如控制器和模型的单独库),您可以多次调用 IncludeXmlComments 方法,它们将全部合并到输出的 Swagger JSON.


仔细按照说明进行操作,您应该得到如下所示的内容:
https://swashbucklenetcore.azurewebsites.net/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。

ASP.Net 个核心项目:

  1. 安装 nuget 包Swashbuckle.AspNetCore.Annotations

  2. [SwaggerOperation(Summary = "Write your summary here")]

    等方法使用 SwaggerOperation 属性
  3. 在 Startup 方法 ConfigureServices 中启用注释,如下所示:

    services.AddSwaggerGen(c =>
    {
        c.EnableAnnotations();
        c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
    });
    
  4. 要排除 public 方法出现在 swagger ui 中,请使用属性 [ApiExplorerSettings(IgnoreApi = true)]。这很有用,因为这些方法可能会因某种原因破坏 swagger。

启动项目,转到 localhost:[端口号]/swagger 并享受。

解决方法是将此添加到您的 .csproj 文件中:

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