最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

在.NET?Core?Web?API中完美配置Swagger文檔的方法

 更新時(shí)間:2024年12月12日 11:33:35   作者:亦世凡華  
這篇文章主要介紹了在.NET?Core?Web?API中完美配置Swagger文檔的方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧

新建項(xiàng)目

打開visual studio創(chuàng)建新項(xiàng)目,這里我們選擇.net core web api模板,然后輸入項(xiàng)目名稱及其解決方案創(chuàng)建新項(xiàng)目

這里使用配置一些其他信息,根據(jù)自己情況進(jìn)行選擇:

創(chuàng)建好項(xiàng)目之后我們可以看到 web api 模板運(yùn)行的項(xiàng)目,相比于MVC模式開發(fā)的項(xiàng)目,初始文件是保留原有的控制器文件但是刪除了模型和視圖文件,而且還加上了兩個(gè)文件,文件的作用相當(dāng)于測(cè)試用例一一可以模擬發(fā)起請(qǐng)求,如下所示:

我們直接運(yùn)行該項(xiàng)目,可以看到我們打開了一個(gè)Swagger文件,對(duì)于后端小白來說可能不太熟悉這個(gè)文件的作用,但是對(duì)于前端開發(fā)者來講可謂是非常熟悉的東西,前端開發(fā)調(diào)用接口就需要經(jīng)常和這個(gè)文件打交道,如下所示:

我們除了可以在Swagger上測(cè)試接口,也可以在本地代碼的測(cè)試用例處點(diǎn)擊發(fā)起請(qǐng)求進(jìn)行測(cè)試:

這里做一個(gè)演示,比如說我們想在Swagger文檔中新增一組接口的話,我們可以在控制器文件中設(shè)置一下get、post、delete、put請(qǐng)求操作,如下我們將原本的文件復(fù)制一份然后命名為First,然后設(shè)置一下接口類型,如下所示:

重新運(yùn)行我們的項(xiàng)目然后打開Swagger,可以看到我們創(chuàng)建的一組接口成功出現(xiàn)了,這里接口的組名可以看到是 FirstController.cs 文件中Controller的前綴,非常好識(shí)別:

RestFul

        背景:近些年來隨著移動(dòng)互聯(lián)網(wǎng)的發(fā)展,前端設(shè)備層出不窮(手機(jī)、平板、桌面電腦、其他專用設(shè)備..),因此必須有一組統(tǒng)一的機(jī)制方便不同的前端設(shè)備與后端進(jìn)行通信,于是RestFul誕生了,它可以通過一套統(tǒng)一的接口為Web,iOS和Android等各種各樣的終端提供服務(wù)。

        特點(diǎn):RestFul把控制器作為維度當(dāng)成一塊資源,對(duì)于這個(gè)資源會(huì)進(jìn)行增刪改查等各種當(dāng)作,這些動(dòng)作必須都得有唯一的URL地址來匹配請(qǐng)求的Method的類型(get、post、put、delete),本質(zhì)上就是用URL定位資源,用HTTP(get、post、put、delete)描述操作。說白了就是一種軟件架構(gòu)設(shè)計(jì)風(fēng)格而不是標(biāo)準(zhǔn),只是提供了一組設(shè)計(jì)原則和約束條件,主要用于客戶端和服務(wù)器交互類的軟件,基于這個(gè)風(fēng)格設(shè)計(jì)的軟件可以更簡(jiǎn)潔有層次,更易于實(shí)現(xiàn)緩存等機(jī)制。

比如上文我們?cè)诳刂破魑募性O(shè)置了一組接口,如果我們?cè)僭谖募刑砑颖热缯f一個(gè)get接口請(qǐng)求,運(yùn)行項(xiàng)目其實(shí)是會(huì)報(bào)錯(cuò)的,為什么?就是因?yàn)檫@兩個(gè)get請(qǐng)求的地址都是一樣的,編輯器沒法識(shí)別到底哪個(gè)get請(qǐng)求是你想要的,為了區(qū)分我們必須設(shè)置唯一的URL地址來避免報(bào)錯(cuò),如下:

重新運(yùn)行項(xiàng)目,可以看到我們?cè)贔irst組當(dāng)中又新增了一個(gè)新的get請(qǐng)求,且兩個(gè)get請(qǐng)求的URL路徑是不一致的,如下所示:

對(duì)于路由約束的類型我們可以參考如下表格,這些都可以作為接口傳參的一個(gè)類型限定:

限制示例匹配示例說明
int{id: int}123456789, -123456789匹配任何整數(shù)
bool{active: bool}true, false匹配true或false,忽略大小寫
datetime{dob: datetime}2024-12-11,2024-12-12 7:32pm匹配滿足datetime類型的值
decimal{price: decimal}49.99, -1,000.01匹配滿足decimal類型的值
double{height: double}1234, -1001.01e8匹配滿足double類型的值
float{height: float}1234, -1001.01e8匹配滿足float類型的值
long{ticks: long}123456789, -123456789匹配滿足long類型的值
minlength(value){usename: minlength(4)}KOBE字符串長(zhǎng)度不能小于4個(gè)字符
maxlength(value){filename: maxlength(8)}CURRY字符串長(zhǎng)度不能超過8個(gè)字符
length(value){filename: length(12)}somefile.txt字符串長(zhǎng)度必須是12個(gè)字符
length(min,max){filename: length(8,16)}somefile.txt字符串長(zhǎng)度必須介于8和16之間
min(value){age: min(18)}20整數(shù)值必須大于18
max(value){age: max(120)}119整數(shù)值必須小于120
range(min, max){age: range(18, 120)}100整數(shù)值必須介于18和120之間
alpha{name: alpha}Rick字符串必須由一或多a-z字母組成
regex(expression){ssn:regex(^\d{3})}3字符串必須匹配指定的正則
required

Swagger配置

        雖然上面我設(shè)置了Swagger并成功運(yùn)行了,但是設(shè)想一個(gè)場(chǎng)景,如果你是后端你寫的代碼你當(dāng)然看的懂,生成的Swagger接口也是知道是什么意思,但是你把這個(gè)Swaager丟給前端,前端是否看的懂呢?如果看不懂是不是還要找后端溝通,這樣就增加了時(shí)間成本。所以后端不僅僅要不接口寫對(duì),還要把Swagger文檔寫好,這里我們就需要對(duì)其進(jìn)行相應(yīng)配置,爭(zhēng)取讓其他人看懂自己寫的接口,這才是真正意義上一名后端應(yīng)該做的事情,如下所示:

注釋展示

注釋是很重要的,當(dāng)我們寫完一個(gè)接口之后我們就需要對(duì)這個(gè)接口的作用進(jìn)行注釋,用來告訴前端后端給的這個(gè)接口作用和意義是什么,如何設(shè)置Swagger注釋展示呢?請(qǐng)往下看:

如下我們給接口代碼寫下注釋,注釋的快捷鍵是///,也就是三個(gè)斜杠即可生成,然后右鍵項(xiàng)目點(diǎn)擊屬性,勾選文檔文件這個(gè)復(fù)選框:

我們右鍵項(xiàng)目重新生成解決方案然后打開我們的項(xiàng)目資源管理目錄,可以看到在我們項(xiàng)目的obj目錄下的最里層有生成了一個(gè)xml文件,右鍵選擇文本打開可以看到我們的注釋就在里面:

接下來如果說我們想把注釋展示到Swagger文檔中的話,我們需要來到入口文件Program.cs對(duì)我們的Swagger進(jìn)行一個(gè)配置,給原本的AddSwaggerGen添加一個(gè)配置對(duì)象,代碼如下:

builder.Services.AddSwaggerGen(option => {
    #region 注釋展示
    {
        // 獲取應(yīng)用程序所在目錄(絕對(duì),不受工作目錄影響,建議采用此方法獲取路徑)
        string basePath = AppContext.BaseDirectory;
        string xmlPath = Path.Combine(basePath, "netCoreWebApi.xml");
        option.IncludeXmlComments(xmlPath);
    }
    #endregion
});

回到Swagger文檔中可以看到我們的注釋已經(jīng)成功的被渲染出來了,方便前端的理解:

版本控制

隨著項(xiàng)目不斷升級(jí)和開發(fā)的過程中,我們還可能需要去對(duì)項(xiàng)目進(jìn)行開發(fā)多個(gè)版本,但是版本之間的Swagger是不同的,不會(huì)放置在同一個(gè)Swagger文檔下面,我們打開Swagger文檔也能看到右上角有個(gè)下拉框,其就是支持不同的版本的切換的,如何做?請(qǐng)往下看:

為了方便不同版本的切換,這里我們直接在解決方案中新建項(xiàng)目設(shè)置一個(gè)獨(dú)立的文件夾出來,因?yàn)榇龝?huì)我們還要對(duì)其作一個(gè)擴(kuò)展,所以這里我們選擇一個(gè)類庫即可,如下:

生成的文件我們重命名為 ApiVersionInfo ,然后設(shè)置靜態(tài)成員V1到V5表明版本有5個(gè),如下所示:

我們來到入口文件Program.cs文件處,這里我們開始設(shè)置支持Swagger版本控制的代碼,這里我們借助 System.Reflection 中的FieldInfo反射機(jī)制中的類型,來獲取類型ApiVersionInfo中的所有字段信息,然后通過OpenApiInfo來描述Swagger文檔的元數(shù)據(jù)及包含了有關(guān)API的關(guān)鍵信息,比如標(biāo)題、版本、描述等,如下所示:

builder.Services.AddSwaggerGen(option => {
    #region 注釋展示
    {
        // 獲取應(yīng)用程序所在目錄(絕對(duì),不受工作目錄影響,建議采用此方法獲取路徑)
        string basePath = AppContext.BaseDirectory;
        string xmlPath = Path.Combine(basePath, "netCoreWebApi.xml");
        option.IncludeXmlComments(xmlPath);
    }
    #endregion
    #region 支持Swagger版本控制
    {
        foreach (FieldInfo filed in typeof(ApiVersionInfo).GetFields())
        {
            option.SwaggerDoc(filed.Name, new OpenApiInfo()
            {
                Title = $"netCoreWebApi API {filed.Name}",
                Version = filed.Name,
                Description = $"netCoreWebApi API {filed.Name} 版本"
            });
        }
    }
    #endregion
});

接下來配置Swagger UI使得每個(gè)API版本都有一個(gè)對(duì)應(yīng)的Swagger UI頁面,具體來說它會(huì)為每個(gè)API版本動(dòng)態(tài)創(chuàng)建一個(gè)Swagger UI的入口從而允許用戶查看不同版本的API文檔,如下:

接下來我們來到編寫接口代碼的控制器文件,給不同版本設(shè)置如下代碼,作用是將特定的API控制器或者方法標(biāo)記為屬于某個(gè)版本組,從而使得Swagger等工具能夠按版本組織和展示API文檔:

最終呈現(xiàn)的效果如下所示:

Token傳值

如果項(xiàng)目的接口需要授權(quán)才能被訪問的話,這里我們就需要通過token傳值的方式來進(jìn)行鑒權(quán)才能調(diào)試接口,如何做呢?請(qǐng)往下看:

這里我們?nèi)匀辉赟wagger配置函數(shù)中設(shè)置token傳值以及添加對(duì)應(yīng)的安全要求,如下所示:

#region 支持token傳值
{
    option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
    {
        Description = "JWT授權(quán)(數(shù)據(jù)將在請(qǐng)求頭中進(jìn)行傳輸) 參數(shù)結(jié)構(gòu): \"Authorization: Bearer {token}\"", // 描述
        Name = "Authorization", // 授權(quán)名稱
        In = ParameterLocation.Header, // 授權(quán)位置,放在頭信息進(jìn)行傳值
        Type = SecuritySchemeType.ApiKey, // 授權(quán)類型
        BearerFormat = "JWT", // 格式是JWT
        Scheme = "Bearer"
    });
    // 添加安全要求
    option.AddSecurityRequirement(new OpenApiSecurityRequirement()
    {
        {
            new OpenApiSecurityScheme
            {
                Reference = new OpenApiReference()
                {
                    Id = "Bearer", // 必須和上面一致
                    Type = ReferenceType.SecurityScheme
                }
            },
            new string[] { }
        }
    });
}
#endregion

運(yùn)行項(xiàng)目來到Swagger文檔中,可以看到我們已經(jīng)成功添加了身份驗(yàn)證,這里我們輸入對(duì)應(yīng)的JWT格式即可,如下所示我們輸入token之后發(fā)起請(qǐng)求,如下已經(jīng)帶上了我們?cè)O(shè)置的token:

方法封裝

根據(jù)上面對(duì)Swagger的配置,可以看到我們對(duì)Swagger的配置基本上都寫在了入口Program.cs文件當(dāng)中,這樣就顯得非常的冗余,入口文件代碼量太多了,這里我們可以將對(duì)Swagger的配置抽離到我們創(chuàng)建的類庫當(dāng)中,新建一個(gè)文件夾用于專門存放Swagger配置的東西,如下所示:

這里設(shè)置一個(gè)函數(shù)然后把IServiceCollection設(shè)置為Service的類型,該類型用于配置依賴注入容器的接口,通常為Swagger配置服務(wù),我們直接把入口文件當(dāng)中配置Swagger的代碼直接粘貼過來:

using System.Reflection;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
namespace netCoreWebApi.WebCore.SwaggerExt
{
    public static class SwaggerExtension
    {
        public static void AddSwaggerExtension(this IServiceCollection Service)
        {
            Service.AddEndpointsApiExplorer();
            Service.AddSwaggerGen(option => {
                #region 注釋展示
                {
                    // 獲取應(yīng)用程序所在目錄(絕對(duì),不受工作目錄影響,建議采用此方法獲取路徑)
                    string basePath = AppContext.BaseDirectory;
                    string xmlPath = Path.Combine(basePath, "netCoreWebApi.xml");
                    option.IncludeXmlComments(xmlPath);
                }
                #endregion
                #region 支持Swagger版本控制
                {
                    foreach (FieldInfo filed in typeof(ApiVersionInfo).GetFields())
                    {
                        option.SwaggerDoc(filed.Name, new OpenApiInfo()
                        {
                            Title = $"netCoreWebApi API {filed.Name}",
                            Version = filed.Name,
                            Description = $"netCoreWebApi API {filed.Name} 版本"
                        });
                    }
                }
                #endregion
                #region 支持token傳值
                {
                    option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
                    {
                        Description = "JWT授權(quán)(數(shù)據(jù)將在請(qǐng)求頭中進(jìn)行傳輸) 參數(shù)結(jié)構(gòu): \"Authorization: Bearer {token}\"", // 描述
                        Name = "Authorization", // 授權(quán)名稱
                        In = ParameterLocation.Header, // 授權(quán)位置,放在頭信息進(jìn)行傳值
                        Type = SecuritySchemeType.ApiKey, // 授權(quán)類型
                        BearerFormat = "JWT", // 格式是JWT
                        Scheme = "Bearer"
                    });
                    // 添加安全要求
                    option.AddSecurityRequirement(new OpenApiSecurityRequirement()
                    {
                        {
                            new OpenApiSecurityScheme
                            {
                                Reference = new OpenApiReference()
                                {
                                    Id = "Bearer", // 必須和上面一致
                                    Type = ReferenceType.SecurityScheme
                                }
                            },
                            new string[] { }
                        }
                    });
                }
                #endregion
            });
        }
        public static void UseSwaggerExtension(this WebApplication app)
        {
            app.UseSwagger();
            app.UseSwaggerUI(option => {
                foreach (FieldInfo filed in typeof(ApiVersionInfo).GetFields())
                {
                    option.SwaggerEndpoint($"/swagger/{filed.Name}/swagger.json", filed.Name);
                }
            });
        }
    }
}

這里還需要在類庫中安裝一下主程序當(dāng)中包,這里注意意義名稱和版本號(hào):

因?yàn)閠his修飾靜態(tài)類中的靜態(tài)方法,上面創(chuàng)建的兩個(gè)方法都是靜態(tài)類中的靜態(tài)方法同時(shí)第一個(gè)參數(shù)還用this進(jìn)行修飾,這種擴(kuò)展方法可以把傳參提到前面當(dāng)成實(shí)例方法來進(jìn)行調(diào)用,接下來我們就在入口文件中調(diào)用這兩個(gè)方法:

最后我們重新運(yùn)行項(xiàng)目,如下可以看到我們的Swagger也可以被重新運(yùn)行:

到此這篇關(guān)于如何在.NET Core Web API中完美配置Swagger文檔的文章就介紹到這了,更多相關(guān).NET Core Web API 配置Swagger文檔內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

大安市| 特克斯县| 双鸭山市| 巴塘县| 缙云县| 高安市| 弥勒县| 顺义区| 陈巴尔虎旗| 巴林右旗| 铁岭市| 额敏县| 金坛市| 正蓝旗| 屯门区| 保定市| 东乡族自治县| 新泰市| 孝昌县| 株洲县| 和政县| 华宁县| 通州市| 高密市| 子长县| 通城县| 抚宁县| 吉林市| 安丘市| 项城市| 平顶山市| 湘乡市| 安乡县| 裕民县| 日喀则市| 龙南县| 蓬莱市| 凌云县| 吐鲁番市| 堆龙德庆县| 墨玉县|