asp.net core 3.0 中使用 swagger
发布于 7 个月前 作者 yan 509 次浏览

asp.net core 3.0 中使用 swagger

Intro

上次更新了 asp.net core 3.0 简单的记录了一下 swagger 的使用,那个项目的 api 比较简单,都是匿名接口不涉及到认证以及 api 版本控制,最近把另外一个 api 项目升级到了 3.0,还是遇到了一些问题,这里单独写一篇文章介绍,避免踩坑。

Swagger 基本使用

swagger 服务注册:

services.AddSwaggerGen(option => 

    { 

        option.SwaggerDoc("sparktodo", new OpenApiInfo 

        { 

            Version = "v1", 

            Title = "SparkTodo API", 

            Description = "API for SparkTodo", 

            Contact = new OpenApiContact() { Name = "WeihanLi", Email = "weihanli@outlook.com" } 

        }); 

        // include document file 

        option.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"{typeof(Startup).Assembly.GetName().Name}.xml"), true); 

    }); 

中间件配置:

//Enable middleware to serve generated Swagger as a JSON endpoint. 

app.UseSwagger(); 

//Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint 

app.UseSwaggerUI(option => 

{ 

    option.SwaggerEndpoint("/swagger/sparktodo/swagger.json", "sparktodo Docs"); 

    option.RoutePrefix = string.Empty; 

    option.DocumentTitle = "SparkTodo API"; 

}); 

为 Swagger 添加 Bearer Token 认证

services.AddSwaggerGen(option => 

{ 

    // ... 

    // Add security definitions 

    option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme() 

    { 

        Description = "Please enter into field the word 'Bearer' followed by a space and the JWT value", 

        Name = "Authorization", 

        In = ParameterLocation.Header, 

        Type = SecuritySchemeType.ApiKey, 

    }); 

    option.AddSecurityRequirement(new OpenApiSecurityRequirement 

    { 

        { new OpenApiSecurityScheme 

        { 

            Reference = new OpenApiReference() 

            { 

                Id = "Bearer", 

                Type = ReferenceType.SecurityScheme 

            } 

        }, Array.Empty<string>() } 

    }); 

}); 

支持多个 ApiVersion

services.AddApiVersioning(options => 

    { 

        options.AssumeDefaultVersionWhenUnspecified = true; 

        options.DefaultApiVersion = ApiVersion.Default; 

        options.ReportApiVersions = true; 

    }); 

services.AddSwaggerGen(option => 

{ 

    // ... 

    option.SwaggerDoc("v1", new OpenApiInfo { Version = "v1", Title = "API V1" }); 

    option.SwaggerDoc("v2", new OpenApiInfo { Version = "v2", Title = "API V2" }); 

    option.DocInclusionPredicate((docName, apiDesc) => 

    { 

        var versions = apiDesc.CustomAttributes() 

            .OfType<ApiVersionAttribute>() 

            .SelectMany(attr => attr.Versions); 

        return versions.Any(v => $"v{v.ToString()}" == docName); 

    }); 

    option.OperationFilter<RemoveVersionParameterOperationFilter>(); 

    option.DocumentFilter<SetVersionInPathDocumentFilter>(); 

}); 

自定义 Api version 相关的 OperationFilter:

public class SetVersionInPathDocumentFilter : IDocumentFilter 

{ 

    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context) 

    { 

        var updatedPaths = new OpenApiPaths(); 

        foreach (var entry in swaggerDoc.Paths) 

        { 

            updatedPaths.Add( 

                entry.Key.Replace("v{version}", swaggerDoc.Info.Version), 

                entry.Value); 

        } 

        swaggerDoc.Paths = updatedPaths; 

    } 

} 

public class RemoveVersionParameterOperationFilter : IOperationFilter 

{ 

    public void Apply(OpenApiOperation operation, OperationFilterContext context) 

    { 

        // Remove version parameter from all Operations 

        var versionParameter = operation.Parameters.Single(p => p.Name == "version"); 

        operation.Parameters.Remove(versionParameter); 

    } 

} 

中间件配置:

//Enable middleware to serve generated Swagger as a JSON endpoint. 

app.UseSwagger(); 

//Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint 

app.UseSwaggerUI(option => 

{ 

    option.SwaggerEndpoint("/swagger/v2/swagger.json", "V2 Docs"); 

    option.SwaggerEndpoint("/swagger/v1/swagger.json", "V1 Docs"); 

    option.RoutePrefix = string.Empty; 

    option.DocumentTitle = "SparkTodo API"; 

}); 

最终 swagger 效果

Memo

上面的配置来自 https://github.com/WeihanLi/SparkTodo 这个项目,要获取代码可以参考这个项目

Reference

回到顶部