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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM