从零开始:如何在.NET Core Web API中完美配置Swagger文档

目录

新建项目

RestFul

Swagger配置

注释展示

版本控制

Token传值

方法封装


新建项目

打开visual studio创建新项目,这里我们选择.net core web api模板,然后输入项目名称及其解决方案创建新项目

这里使用配置一些其他信息,根据自己情况进行选择:

创建好项目之后我们可以看到 web api 模板运行的项目,相比于MVC模式开发的项目,初始文件是保留原有的控制器文件但是删除了模型和视图文件,而且还加上了两个文件,文件的作用相当于测试用例一一可以模拟发起请求,如下所示:

我们直接运行该项目,可以看到我们打开了一个Swagger文件,对于后端小白来说可能不太熟悉这个文件的作用,但是对于前端开发者来讲可谓是非常熟悉的东西,前端开发调用接口就需要经常和这个文件打交道,如下所示:

我们除了可以在Swagger上测试接口,也可以在本地代码的测试用例处点击发起请求进行测试:

这里做一个演示,比如说我们想在Swagger文档中新增一组接口的话,我们可以在控制器文件中设置一下get、post、delete、put请求操作,如下我们将原本的文件复制一份然后命名为First,然后设置一下接口类型,如下所示:

重新运行我们的项目然后打开Swagger,可以看到我们创建的一组接口成功出现了,这里接口的组名可以看到是 FirstController.cs 文件中Controller的前缀,非常好识别:

RestFul

        背景:近些年来随着移动互联网的发展,前端设备层出不穷(手机、平板、桌面电脑、其他专用设备..),因此必须有一组统一的机制方便不同的前端设备与后端进行通信,于是RestFul诞生了,它可以通过一套统一的接口为Web,iOS和Android等各种各样的终端提供服务。

        特点:RestFul把控制器作为维度当成一块资源,对于这个资源会进行增删改查等各种当作,这些动作必须都得有唯一的URL地址来匹配请求的Method的类型(get、post、put、delete),本质上就是用URL定位资源,用HTTP(get、post、put、delete)描述操作。说白了就是一种软件架构设计风格而不是标准,只是提供了一组设计原则和约束条件,主要用于客户端和服务器交互类的软件,基于这个风格设计的软件可以更简洁有层次,更易于实现缓存等机制。

比如上文我们在控制器文件中设置了一组接口,如果我们再在文件中添加比如说一个get接口请求,运行项目其实是会报错的,为什么?就是因为这两个get请求的地址都是一样的,编辑器没法识别到底哪个get请求是你想要的,为了区分我们必须设置唯一的URL地址来避免报错,如下:

重新运行项目,可以看到我们在First组当中又新增了一个新的get请求,且两个get请求的URL路径是不一致的,如下所示:

对于路由约束的类型我们可以参考如下表格,这些都可以作为接口传参的一个类型限定:

限制示例匹配示例说明
int{id: int}123456789, -123456789匹配任何整数
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字符串长度不能小于4个字符
maxlength(value){filename: maxlength(8)}CURRY字符串长度不能超过8个字符
length(value){filename: length(12)}somefile.txt字符串长度必须是12个字符
length(min,max){filename: length(8,16)}somefile.txt字符串长度必须介于8和16之间
min(value){age: min(18)}20整数值必须大于18
max(value){age: max(120)}119整数值必须小于120
range(min, max){age: range(18, 120)}100整数值必须介于18和120之间
alpha{name: alpha}Rick字符串必须由一或多a-z字母组成
regex(expression){ssn:regex(^\d{3})}3字符串必须匹配指定的正则
required

Swagger配置

        虽然上面我设置了Swagger并成功运行了,但是设想一个场景,如果你是后端你写的代码你当然看的懂,生成的Swagger接口也是知道是什么意思,但是你把这个Swaager丢给前端,前端是否看的懂呢?如果看不懂是不是还要找后端沟通,这样就增加了时间成本。所以后端不仅仅要不接口写对,还要把Swagger文档写好,这里我们就需要对其进行相应配置,争取让其他人看懂自己写的接口,这才是真正意义上一名后端应该做的事情,如下所示:

注释展示

注释是很重要的,当我们写完一个接口之后我们就需要对这个接口的作用进行注释,用来告诉前端后端给的这个接口作用和意义是什么,如何设置Swagger注释展示呢?请往下看:

如下我们给接口代码写下注释,注释的快捷键是///,也就是三个斜杠即可生成,然后右键项目点击属性,勾选文档文件这个复选框:

我们右键项目重新生成解决方案然后打开我们的项目资源管理目录,可以看到在我们项目的obj目录下的最里层有生成了一个xml文件,右键选择文本打开可以看到我们的注释就在里面:

接下来如果说我们想把注释展示到Swagger文档中的话,我们需要来到入口文件Program.cs对我们的Swagger进行一个配置,给原本的AddSwaggerGen添加一个配置对象,代码如下:

builder.Services.AddSwaggerGen(option => {#region 注释展示{// 获取应用程序所在目录(绝对,不受工作目录影响,建议采用此方法获取路径)string basePath = AppContext.BaseDirectory;string xmlPath = Path.Combine(basePath, "netCoreWebApi.xml");option.IncludeXmlComments(xmlPath);}#endregion
});

回到Swagger文档中可以看到我们的注释已经成功的被渲染出来了,方便前端的理解:

版本控制

随着项目不断升级和开发的过程中,我们还可能需要去对项目进行开发多个版本,但是版本之间的Swagger是不同的,不会放置在同一个Swagger文档下面,我们打开Swagger文档也能看到右上角有个下拉框,其就是支持不同的版本的切换的,如何做?请往下看:

为了方便不同版本的切换,这里我们直接在解决方案中新建项目设置一个独立的文件夹出来,因为待会我们还要对其作一个扩展,所以这里我们选择一个类库即可,如下:

生成的文件我们重命名为 ApiVersionInfo ,然后设置静态成员V1到V5表明版本有5个,如下所示:

我们来到入口文件Program.cs文件处,这里我们开始设置支持Swagger版本控制的代码,这里我们借助 System.Reflection 中的FieldInfo反射机制中的类型,来获取类型ApiVersionInfo中的所有字段信息,然后通过OpenApiInfo来描述Swagger文档的元数据及包含了有关API的关键信息,比如标题、版本、描述等,如下所示:

builder.Services.AddSwaggerGen(option => {#region 注释展示{// 获取应用程序所在目录(绝对,不受工作目录影响,建议采用此方法获取路径)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使得每个API版本都有一个对应的Swagger UI页面,具体来说它会为每个API版本动态创建一个Swagger UI的入口从而允许用户查看不同版本的API文档,如下:

接下来我们来到编写接口代码的控制器文件,给不同版本设置如下代码,作用是将特定的API控制器或者方法标记为属于某个版本组,从而使得Swagger等工具能够按版本组织和展示API文档:

最终呈现的效果如下所示:

Token传值

如果项目的接口需要授权才能被访问的话,这里我们就需要通过token传值的方式来进行鉴权才能调试接口,如何做呢?请往下看:

这里我们仍然在Swagger配置函数中设置token传值以及添加对应的安全要求,如下所示:

#region 支持token传值
{option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme(){Description = "JWT授权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\"", // 描述Name = "Authorization", // 授权名称In = ParameterLocation.Header, // 授权位置,放在头信息进行传值Type = SecuritySchemeType.ApiKey, // 授权类型BearerFormat = "JWT", // 格式是JWTScheme = "Bearer"});// 添加安全要求option.AddSecurityRequirement(new OpenApiSecurityRequirement(){{new OpenApiSecurityScheme{Reference = new OpenApiReference(){Id = "Bearer", // 必须和上面一致Type = ReferenceType.SecurityScheme}},new string[] { }}});
}
#endregion

运行项目来到Swagger文档中,可以看到我们已经成功添加了身份验证,这里我们输入对应的JWT格式即可,如下所示我们输入token之后发起请求,如下已经带上了我们设置的token:

方法封装

根据上面对Swagger的配置,可以看到我们对Swagger的配置基本上都写在了入口Program.cs文件当中,这样就显得非常的冗余,入口文件代码量太多了,这里我们可以将对Swagger的配置抽离到我们创建的类库当中,新建一个文件夹用于专门存放Swagger配置的东西,如下所示:

这里设置一个函数然后把IServiceCollection设置为Service的类型,该类型用于配置依赖注入容器的接口,通常为Swagger配置服务,我们直接把入口文件当中配置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 注释展示{// 获取应用程序所在目录(绝对,不受工作目录影响,建议采用此方法获取路径)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授权(数据将在请求头中进行传输) 参数结构: \"Authorization: Bearer {token}\"", // 描述Name = "Authorization", // 授权名称In = ParameterLocation.Header, // 授权位置,放在头信息进行传值Type = SecuritySchemeType.ApiKey, // 授权类型BearerFormat = "JWT", // 格式是JWTScheme = "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);}});}}
}

这里还需要在类库中安装一下主程序当中包,这里注意意义名称和版本号:

因为this修饰静态类中的静态方法,上面创建的两个方法都是静态类中的静态方法同时第一个参数还用this进行修饰,这种扩展方法可以把传参提到前面当成实例方法来进行调用,接下来我们就在入口文件中调用这两个方法:

最后我们重新运行项目,如下可以看到我们的Swagger也可以被重新运行:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/889215.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

百度搜索应适用中文域名国家标准,修复中文网址展示BUG

12月1日中文域名国家标准正式实施。该标准“明确了中文域名在编码、解析、注册、字表等方面的技术要求,适用于中文域名注册管理机构、注册服务机构、网络软硬件服务商及终端用户”。 00:23 显然,百度作为网络软硬件服务商,是包括在国家标准的…

Windows安装elasticsearch、Kibana以及IK分词器

一、下载 1.下载elasticsearch 访问官网Download Elasticsearch | Elastic,下载elasticsearch 2.下载 Kibana 访问Download Kibana Free | Get Started Now | Elastic ,下载 Kibana 3. IK分词器下载 访问Gitee 极速下载/elasticsearch-analysis-ik选…

第一个C++程序--(蓝桥杯备考版)

第一个C程序 基础程序 #include <iostream>//头⽂件 using namespace std;//使⽤std的名字空间 int main()//main函数 {cout << "hello world!" << endl; //输出&#xff1a;在屏幕打印"hello world!" return 0;}main函数 main 函数是…

Elasticsearch Serverless 中的数据流自动分片

作者&#xff1a;来自 Elastic Andrei Dan 在 Elastic Cloud Serverless 中&#xff0c;我们根据索引负载自动为数据流配置最佳分片数量&#xff0c;从而使用户无需摆弄分片。 传统上&#xff0c;用户会更改数据流的分片配置&#xff0c;以处理各种工作负载并充分利用可用资源。…

TcpServer 服务器优化之后,加了多线程,对心跳包进行优化

TcpServer 服务器优化之后&#xff0c;加了多线程&#xff0c;对心跳包进行优化 TcpServer.h #ifndef TCPSERVER_H #define TCPSERVER_H#include <iostream> #include <winsock2.h> #include <ws2tcpip.h> #include <vector> #include <map> #…

python进阶-05-利用Selenium来实现动态爬虫

python进阶-05-利用Selenium来实现动态爬虫 一.说明 这是python进阶部分05&#xff0c;我们上一篇文章学习了Scrapy来爬取网站&#xff0c;但是很多网站需要登录才能爬取有用的信息&#xff0c;或者网站的静态部分是一个空壳&#xff0c;内容是js动态加载的,或者人机验证&…

Linux —— vim 编辑器

一、什么是vim vim是一个功能强大、高度可定制的文本编辑器。以下是对vim编辑器的具体介绍&#xff1a; 历史背景&#xff1a;vim最初由Bram Moolenaar在1991年开发&#xff0c;作为vi编辑器的增强版&#xff0c;增加了许多新的特性和改进。它继承了vi的基本编辑功能和键盘快捷…

高效率同步降压转换器 - YB2416D: 实现快速充电和高效能供电的利器

概述: YB2416是一款输入耐压超过40V&#xff0c;在4.5V~30V输入电压条件下正常工作&#xff0c;并且能够实现精确恒压以及恒流的同步降压型DC-DC转换器。 内部集成80m2的上管和40m2的下管&#xff0c;无需外部肖特基二极管&#xff0c;可连续输出3A电流。输出3A电流时系统转换…

Repo管理

文章目录 前言Repo介绍清单仓库清单仓库的组成 初始化Repo同步远程仓库Repo实际应用 前言 我们知道&#xff0c;Git是用来管理某一个仓库&#xff0c;那当一个项目用到了多个仓库时&#xff0c;怎么来同步管理这些仓库呢&#xff1f;这个时候就可以引入Repo管理。 Repo介绍 …

神经网络的起源与工作原理

神经网络起源&#xff1a;一个生物神经网络是由一组化学上相连或功能上相关的神经元组成。一个神经元可能与许多其他神经元相连&#xff0c;网络中的神经元和连接的总数可能很广泛。连接&#xff0c;称为突触&#xff0c;通常是从轴突到树突形成的&#xff0c;尽管树突和其他连…

Qwen2.5-7B-Instruct vLLM 部署调用

Qwen2.5-7B-Instruct vLLM 部署调用 vLLM 简介 vLLM 框架是一个高效的大语言模型推理和部署服务系统&#xff0c;具备以下特性&#xff1a; 高效的内存管理&#xff1a;通过 PagedAttention 算法&#xff0c;vLLM 实现了对 KV 缓存的高效管理&#xff0c;减少了内存浪费&…

解决 Mac(M1/M2)芯片,使用node 14版本

前言 nvm 在安装 Node.js v14.21.3 时&#xff0c;报错&#xff1a; nvm install 14 Downloading and installing node v14.21.3... Downloading https://nodejs.org/dist/v14.21.3/node-v14.21.3-darwin-arm64.tar.xz... curl: (56) The requested URL returned error: 404Bin…

TesseractOCR-GUI:基于WPF/C#构建TesseractOCR简单易用的用户界面

前言 前篇文章使用Tesseract进行图片文字识别介绍了如何安装TesseractOCR与TesseractOCR的命令行使用。但在日常使用过程中&#xff0c;命令行使用还是不太方便的&#xff0c;因此今天介绍一下如何使用WPF/C#构建TesseractOCR简单易用的用户界面。 普通用户使用 参照上一篇教…

【ETCD】【源码阅读】configurePeerListeners() 函数解析

configurePeerListeners 是 ETCD 的一个核心函数&#xff0c;用于为集群中节点之间的通信配置监听器&#xff08;Peer Listener&#xff09;。这些监听器主要负责 Raft 协议的消息传递、日志复制等功能。函数返回一个包含所有监听器的列表。 函数签名 func configurePeerList…

uniapp改成用vue起项目

目的&#xff1a;让项目按照vue的打包流程跑流水线 1.按照uniapp官网教程执行 2.执行第二条命令时报错 ERROR Failed to get response from true/vue-cli-version-marker 3.解决方式 报错可能跟yarn有关&#xff0c;然后切换成npm 找到自己本地电脑的这个文件 按照截图修…

【SH】微信小程序调用EasyDL零门槛AI开发平台的图像分类研发笔记

文章目录 微信小程序字符串字符串模板字符串拼接 上传图片编写JS代码编写wxml代码编写wxss代码 GET请求测试编写测试代码域名不合法问题 GET和POST请求测试编写JS代码编写wxml代码编写wxss代码 效果展示 微信小程序字符串 字符串模板 这是ES6引入的特性&#xff0c;允许你通过…

[小白系列]Ubuntu安装教程-安装prometheus和Grafana

Docker安装prometheus 拉取镜像 docker pull prom/prometheus 配置文件prometheus.yml 在/data/prometheus/建立prometheus.yml配置文件。&#xff08;/data/prometheus/可根据自己需要调整&#xff09; global:scrape_interval: 15s # By default, scrape targets ev…

[大数据]Hudi编译集成

1. Hudi概述 1.1 Hudi简介 What is Apache Hudi Apache Hudi is the next generation streaming data lake platform. Apache Hudi brings core warehouse and database functionality directly to a data lake. Hudi provides tables, transactions, efficient upserts/dele…

windows下 mysql开启 binlog日志

一、查看是否开启 binlog -- 方式一 show binary logs;-- 方式二 show VARIABLES like log_bin 说明没有开启 方式一 &#xff1a;you are not using binary logging 方式二&#xff1a;log_bin off 二、编辑 my.ini 配置文件 默认安装地点位于&#xff1a;C:\ProgramDat…

Java-22 深入浅出 MyBatis - 手写ORM框架3 手写SqlSession、Executor 工作原理

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大数据篇正在更新&#xff01;https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了&#xff1a; MyBatis&#xff…