【问题标题】:How to add method description in Swagger UI in WebAPI Application如何在 WebAPI 应用程序的 Swagger UI 中添加方法描述
【发布时间】:2019-03-23 19:41:24
【问题描述】:

我使用 Swagger 作为我的 API 工具框架,到目前为止效果很好。我刚看到这个页面https://petstore.swagger.io/

并看到每种方法都有描述。例如,

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

【问题讨论】:

    标签: c# asp.net-core-webapi swagger-ui restful-url swashbuckle


    【解决方案1】:

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


    包括来自 XML 注释的描述

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

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

    此时,任何未使用 XML cmets 注释的类或方法都会触发构建警告。要抑制这种情况,请在属性对话框的“抑制警告”字段中输入警告代码“1591”。

    2 - 配置 Swashbuckle 以将文件中的 XML cmets 合并到生成的 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 字段。

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


    仔细按照说明进行操作,您应该会得到如下所示的内容:
    https://swashbucklenetcore.azurewebsites.net/swagger/

    【讨论】:

    • 感谢您的回答。但是页面上没有任何地方说我的MyApi.xml 应该是什么样子?
    • @WorkBee 你真的不需要看看 XML 应该是什么样子......它是由 VisualStudio 从你的注释自动生成的,swachbuckle 知道如何阅读它......还有名字@ 987654329@ 只是一个示例,您可以随意命名,只需在整个解决方案中保持相同即可
    • 这是关于如何在 Swagger 中使用描述的非常好的描述,正如@HelderSepulveda 所说,您在步骤 1 中所做的设置就是您生成该 XML 文件的位置。您也可以在此处输入任何名称,但请确保在第 2 步中使用相同的名称(描述为 MyApi.xml)
    • 这正是我整个下午一直在寻找的。为了让我的 XML cmets 显示在 Swagger UI 查询字符串的描述中,我检查了项目属性中的 XML documentation file 设置并添加了 IncludeXmlComments(filepath)。谢谢!
    【解决方案2】:

    对于 ASP.Net Core 项目:

    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. 要排除公共方法出现在 swagger ui 中使用属性[ApiExplorerSettings(IgnoreApi = true)]。这很有用,因为这些方法可能会因某种原因而破坏 swagger。

    启动项目,进入 localhost:[端口号]/swagger 即可享受。

    【讨论】:

    • tnx 为您的解决方案,我的代码也与两个使用冲突,它适用于:[Swashbuckle.AspNetCore.Annotations.SwaggerOperation(Summary = "")]
    • 我认为这是正确的答案,这是 OP 期望能够开箱即用的。这只是来自与原始 Swashbuckle 相同的开发人员的附加包。
    【解决方案3】:

    我们使用额外的属性向 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()
        {
            ...
        }
    

    然后在你招摇的配置中确保应用这些过滤器:

    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 文档不是一个可行的方法。首先,XML 文档用 .NET 术语描述了所有内容。想象一下,您的 REST 使用 ABAP 开发人员。第二个 - 分发 XML 文档的根本原因是什么?第三个 - 如果我想要本地化文档怎么办?
    • 没有人在阅读 XML 文档本身。为什么这会关注 ABAP 开发人员?它不被接受,因为另一个问题以本机方式用更少的代码回答了这个问题。
    • 我从以下链接newbedev.com/… 在 .net 核心中找到了一些可以执行此操作的内容
    【解决方案4】:

    对于那些希望能够公开自定义本地化控制器名称和操作描述而无需将 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。

    【讨论】:

      【解决方案5】:

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

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

      【讨论】:

      • 这是通过项目属性执行此操作的结果是 Visual Studio。右键单击(您的项目)> 属性 > 构建 > 输出部分 > 选中“XML 文档文件”>
      【解决方案6】:

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

      【讨论】:

      • 如果您在 Swagger 配置中指定 IncludeXmlComments 并在项目的属性中启用输出,即。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-10
      • 2021-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多