asp.net core 3.0 中使用 swagger


asp.net core 3.0 中使用 swagger

Intro

上次更新了 asp.net core 3.0 簡單的記錄了一下 swagger 的使用 ,詳細可以參考asp.net core3.0更新簡記,那個項目的 api 比較簡單,都是匿名接口不涉及到認證以及 api 版本控制,最近把另外一個 api 項目升級到了 3.0,還是遇到了一些問題,這里單獨寫一篇文章介紹,避免踩坑。

Swagger 基本使用

安裝 nuget 包 Swashbuckle.AspNetCore,需要使用 5.0.x 版本,使用最新的 5.0.0-rc 版本(還沒發穩定版,需要顯示預覽版本才能看到)

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


免責聲明!

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



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