zoukankan      html  css  js  c++  java
  • asp.net core 3.1/swagger

     

    本文使用特性来描述接口而不是xml文件,使用特性可自定义接口在swaggerUI上的描述

    安装nuget包:Swashbuckle.AspNetCore.SwaggerUISwashbuckle.AspNetCore.Annotations,配置swagger:

    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.OpenApi.Models;
    ​
    namespace swaggerweb
    {
        public class Startup
        {
            private readonly string swaggerDocName = "weather";
    ​
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    ​
            public IConfiguration Configuration { get; }
    ​
            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddSwaggerGen(opt =>
                {
                    opt.SwaggerDoc(swaggerDocName, new OpenApiInfo()
                    {
                        Version = "v1",
                        Title = "WeatherForecast",
                        Description = "天气预报"
                    });
                    // 使用annotation来描述接口,不依赖XML文件
                    opt.EnableAnnotations();
    ​
                    // 下面两句,将swagger文档中controller名使用GroupName替换
                    // 在Swagger中,一个Tag可以看作是一个API分组
                    opt.DocInclusionPredicate((_, apiDescription) => string.IsNullOrWhiteSpace(apiDescription.GroupName) == false);
                    opt.SwaggerGeneratorOptions.TagsSelector = (apiDescription) => new[] { apiDescription.GroupName };
                });
                services.AddControllers();
            }
    ​
            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                app.UseSwagger(opt =>
                {
                    // 相对路径加载swagger文档
                    //opt.RouteTemplate = "swagger/{documentName}";
                })
                .UseSwaggerUI(opt =>
                {
                    opt.SwaggerEndpoint($"{swaggerDocName}/swagger.json", "天气预报API文档");
                });
    ​
                app.UseRouting();
    ​
                app.UseAuthorization();
    ​
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();
                    // 也可以在这里配置swagger文档路径
                    //endpoints.MapSwagger();
                });
            }
        }
    }

    Controller和Action上使用特性:ApiExplorerSettingsSwaggerOperation

    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Extensions.Logging;
    using Swashbuckle.AspNetCore.Annotations;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    ​
    namespace swaggerweb.Controllers
    {
        [ApiExplorerSettings(GroupName = "天气预报")]
        [Route("[controller]")]
        public class WeatherForecastController : ControllerBase
        {
            private static readonly string[] Summaries = new[]
            {
                "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
            };
    ​
            private readonly ILogger<WeatherForecastController> _logger;
    ​
            public WeatherForecastController(ILogger<WeatherForecastController> logger)
            {
                _logger = logger;
            }
    ​
            [HttpGet]
            [SwaggerOperation(Summary = "获取天气预报信息")]
            public IEnumerable<WeatherForecast> Get()
            {
                var rng = new Random();
                return Enumerable.Range(1, 5).Select(index => new WeatherForecast
                {
                    Date = DateTime.Now.AddDays(index),
                    TemperatureC = rng.Next(-20, 55),
                    Summary = Summaries[rng.Next(Summaries.Length)]
                })
                .ToArray();
            }
        }
    }

    效果图:

     

    2020-07-28 补充

    1. 默认折叠swagger 文档

    当接口比较多时,展开Tag看起来比较费力,这里折叠下

    public void Configure(IApplicationBuilder app, IHostEnvironment env)
    {
        app.UseSwagger().UseSwaggerUI(opt =>
        {
            // 折叠所有的Tag
            opt.DocExpansion(DocExpansion.None);
            // 隐藏API中定义的model
            opt.DefaultModelsExpandDepth(-1);
        });
    }

    2. 添加Authorization请求头

    有些接口需要认证/授权,这里针对ASP.NET Core中在Controller上标记Authorize特性的情况,使用swagger中的自定义Filter来实现在swagger界面上发起请求时传递授权token

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSwaggerGen(opt =>
        {
            opt.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
            {
                Scheme = "bearer",
                BearerFormat = "JWT",
                Description = "JWT Authorization header using the Bearer scheme. Example: "Authorization: Bearer {token}"",
                Name = "Authorization",
                In = ParameterLocation.Header,
                Type = SecuritySchemeType.Http
            });
            opt.OperationFilter<AuthenticationOperationFilter>();
        });
    }

    自定义过滤器:

    public class AuthenticationOperationFilter : IOperationFilter
    {
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var actionScopes = context.MethodInfo.GetCustomAttributes(true).OfType<AuthorizeAttribute>().Select(attr => attr.TypeId.ToString()).Distinct();
            var controllerScopes = context.MethodInfo.DeclaringType!.GetCustomAttributes(true)
                .Union(context.MethodInfo.GetCustomAttributes(true))
                .OfType<AuthorizeAttribute>()
                .Select(attr => attr.TypeId.ToString());
            var requiredScopes = actionScopes.Union(controllerScopes).Distinct().ToArray();
            if (requiredScopes.Any())
            {
                operation.Responses.Add("401", new OpenApiResponse { Description = "Unauthorized" });
                operation.Responses.Add("419", new OpenApiResponse { Description = "AuthenticationTimeout" });
                operation.Responses.Add("403", new OpenApiResponse { Description = "Forbidden" });
                var oAuthScheme = new OpenApiSecurityScheme
                {
                    Scheme = "Bearer",
                    Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "Bearer" }
                };
                operation.Security = new List<OpenApiSecurityRequirement>
                {
                    new OpenApiSecurityRequirement
                    {
                        [ oAuthScheme ] = new List<string>()
                    }
                };
            }
        }
    }

    swagger界面上,每个API及swagger顶部均会出现小锁,点击小锁可以输入token:

    3. 序列化问题

    发现API中若定义了IDictionary<,>类型的字段,swagger默认的序列化方式会出错,这里使用Newtonsoft来序列化。需要安装nuget包:Swashbuckle.AspNetCore.Newtonsoft:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSwaggerGen().AddSwaggerGenNewtonsoftSupport();
    }

    推荐阅读

    Grouping Operations With Tags

  • 相关阅读:
    pdb文件转
    C#是.NET吗?hr说:我们只招聘C#工程师,你是做.NET的和我们要求不符。。。
    C#中的==、Equal、ReferenceEqual > 转
    常用HTML代码转
    SQL Server数据库字段数据类型
    jQuery性能优化的28个建议 转
    收尾
    OSI七层网络协议之传输层
    将其他程序中的大纲文本插入到 PowerPoint 演示文稿中
    Applet 编程中多媒体文件放置的位置
  • 原文地址:https://www.cnblogs.com/Cwj-XFH/p/12922608.html
Copyright © 2011-2022 走看看