基于dotNET 5 MVC经典模式引入Swagger进行web api开发和管理发布OAS3标准接口文档全过程
Swagger 是一个规范且完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。
Swagger 的目标是对 REST API 定义一个标准且和语言无关的接口,可以让人和计算机拥有无需访问源码、文档或网络流量监测就可以发现和理解服务的能力。当通过 Swagger 进行正确定义,用户可以理解远程服务并使用最少实现逻辑与远程服务进行交互。与为底层编程所实现的接口类似,Swagger 消除了调用服务时可能会有的猜测。
- 面向web api开发
- 什么是Swagger
- 什么是OAS3
- 在dotNet Core和dotNET 5的web api项目中引入Swagger
- 在dotNet Core和dotNET 5的MVC项目中引入Swagger
- 注解格式
- 相关资料
# 面向web api开发
大家在开发完 webapi 后,经常为了方便接口双方对接,需要将 webapi 接口文档化,那有没有什么快捷可交互的文档呢?可以利用快捷工具 Swagger,它的可视化 UI 可轻松助你 API 文档化的同时还方便测试 API。
Swashbuckle 就是一个用于生成 Swagger 文档的开源工具包,这篇文章将会讨论如何利用 Swashbuckle 来为你的 Restful API 生成可交互的文档。
# 什么是Swagger
Swagger 是一个规范且完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。 Swagger 的目标是对 REST API 定义一个标准且和语言无关的接口,可以让人和计算机拥有无需访问源码、文档或网络流量监测就可以发现和理解服务的能力。当通过 Swagger 进行正确定义,用户可以理解远程服务并使用最少实现逻辑与远程服务进行交互。与为底层编程所实现的接口类似,Swagger 消除了调用服务时可能会有的猜测。
Swagger 的优势
- 支持 API 自动生成同步的在线文档:使用 Swagger 后者可以直接通过代码生成文档,不再需要自己手动编写接口文档了,对程序员来说非常方便,可以节约写文档的时间去学习新技术。
- 提供 Web 页面在线测试 API:光有文档还不够,Swagger 生成的文档还支持在线测试。参数和格式都定好了,直接在界面上输入参数对应的值即可在线测试接口。
说白了就是一种接口文档,而且支持在线调试,从而提升web api开发的效率。 其它同类型的工具还有apidoc,如:https://code.z01.com/apidoc/ 就是用apidoc生成,可以检索、遍历,缺点是不能调试。 来自Java开源社区的Swagger则功能更加强大,自然受人欢迎。
一句话: *** dotNET CORE Swagger的使用,写好注释就是写好接口文档***
其运界面如下所示:
# 什么是OAS3
作为一个经常要提供给API文档给内部和第三方的阅读的“苦程”,我一直在寻找一个完美的Spring MVC文档解决方案。过去,我一直使用的是springfox-swagger2依赖,使用swagger2注解,对代码进行注释,生成swagger文档。 不过,早在2020年Swagger2就已过时,springfox-swagger2也已停止维护。业界普遍转向了OAS3 规范管理文档接口,这也是当前OpenApi规范标准。
# 在dotNet Core和dotNET 5的web api项目中引入Swagger
注意:这里是web api 项目,在vs 2019中创建项目如下:
# 1、新建一个asp.net core web api项目
# 2、Nuget安装Swagger
# 3、为接口及接口中用到的类添加注释
# 4、右键项目属性(如果项目中有其他库的,都需要参照配置下)生成XML文档,如下图打勾保存
# 5、Startup配置Swagger,这里用到了一个自定义的扩展类:
SwaggerHttpHeaderOperation
,这个类里面增加了调试的Http请求header参数,比如Token就可以扩展下,这样在调试时就可以填写该参数,方便调试需要鉴权的接口。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.IO;
using System.Text;
namespace ZQSwaggerDemo
{
public class Startup
{
const string PROJECTNAME = "知擎物联API";
const string VERSION = "v1.0.0";
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.AddControllers();
//配置swagger
StringBuilder fDescription = new StringBuilder();
fDescription.Append("<a target='_blank' href='https://www.yyzq.net' class='link'>常州知擎物联科技有限公司 版权所有</a>");
fDescription.Append($"<br>API适用标注说明:");
fDescription.Append($"<br><span style='color:blue'>【NOTOKEN】</span>:无需登录可访问");
services.AddSwaggerGen(c =>
{
c.OperationFilter<SwaggerHttpHeaderOperation>();
c.SwaggerDoc(VERSION, new Microsoft.OpenApi.Models.OpenApiInfo()
{
Title = PROJECTNAME,
Version = VERSION,
Description = ""
}); ;
//加载注释xml文件(这里演示的代码是为了方便一次性加载多个XML文档,省去了一个个XML文件添加的繁琐)
string[] files = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "ZQ*.xml");
foreach (string item in files)
{
c.IncludeXmlComments(item);
}
});
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseSwagger();//启用中间件服务生成Swagger作为JSON终结点
app.UseSwaggerUI(c =>
{
//启用中间件服务对swagger-ui,指定Swagger JSON终结点
c.SwaggerEndpoint($"/swagger/{VERSION}/swagger.json", PROJECTNAME);
});
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace ZQSwaggerDemo
{
/// <summary>
/// Swagger调试header
/// </summary>
public class SwaggerHttpHeaderOperation : IOperationFilter
{
/// <summary>
///
/// </summary>
/// <param name="operation"></param>
/// <param name="context"></param>
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
operation.Parameters.Add(new OpenApiParameter()
{
Name = "Token",
In = ParameterLocation.Header,
Required = false,
Schema = new OpenApiSchema { Type = "string" }
});
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 6、启动项目,访问:
http://localhost:45039/swagger/index.html 可以看到之前写的注释都在文档中体现了出来
# 7、调试接口
对想要调试的接口,展开接口后,点击Try it out按钮,这里我们可以看到之前扩展的Header部分参数(本DEMO仅示范,并未使用,实际项目中还是经常需要自定义一些header参数),填写好参数后,点击Execute调用接口,可以看到成功返回了数据。
# 在dotNet Core和dotNET 5的MVC项目中引入Swagger
上面的一节,我们介绍了在web api项目中引入swagger,但大多数项目不是web api项目,而是经典的mvc项目,要如何应用呢? 别急,这里开始分享全过程。
# 一.新建项目: dotnet new mvc -n SwaggerTest
# 二.添加nuget引用 :dotnet add TodoApi.csproj package Swashbuckle.AspNetCore -v 5.0.0
也可以使用 Package Manager Console
# 三.Startup中的ConfigureServices 添加服务
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Microsoft.OpenApi.Models.OpenApiInfo { Title = "Docs", Version = "V1" });
});
2
3
4
5
# 四.在Startup中的Configure使用 代码如下
app.UseSwagger();
app.UseSwaggerUI(c=>c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1"));
2
3
# 五.在HomeController添加如下代码
public class HomeController : Controller
{
/// <param name="name"></param>
[HttpPost("{name}")]
public IActionResult Find(string name)
{
if (string.IsNullOrWhiteSpace(name)) return NotFound();
else return Content(name);
}
}
2
3
4
5
6
7
8
9
10
# 六.测试
如果上面文档不足,还要可以补充看下面的:
# 安装 Swagger 中间件
要想利用 Swagger 文档化,需要 nuget 引用 Swashbuckle.AspNetCore 包,还可以通过 Visual Studio 2019 的 NuGet package manager 可视化界面安装 或者 通过 NuGet package manager 命令行工具输入以下命令:
dotnet add package Swashbuckle.AspNetCore
# 配置 Swagger 中间件
为了配置 Swagger,在 Startup.ConfigureServices
方法中添加如下代码,注意下面的 AddSwaggerGen 方法是用于给 API 文档 添加一些元数据。
services.AddSwaggerGen(c =>;
{
c.SwaggerDoc("v1", new Info
{
Version = "v1",
Title = "Swagger Demo",
Description = "Swagger Demo for ValuesController",
TermsOfService = "None",
Contact = new Contact() { Name = "Joydip Kanjilal",
Email = "joydipkanjilal@yahoo.com",
Url = "www.google.com" }
});
});
2
3
4
5
6
7
8
9
10
11
12
13
14
接下来就要启动 Swagger了,在 Startup.Configure 方法下添加如下代码:
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
});
2
3
4
5
为了完整性,下面是 Startup
中的所有代码清单。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Swashbuckle.AspNetCore.Swagger;
namespace IDGSwaggerDemo
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion
(CompatibilityVersion.Version_2_2);
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info
{
Version = "v1",
Title = "Swagger Demo",
Description = "Swagger Demo for ValuesController",
TermsOfService = "None",
Contact = new Contact() { Name = "Joydip Kanjilal",
Email = "joydipkanjilal@yahoo.com",
Url = "www.google.com"
}
});
});
}
public void Configure(IApplicationBuilder app,
IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseMvc();
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
});
}
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 浏览 Swagger UI
现在我们运行一下应用程序来浏览一下 Swagger UI 地址,可以看到 UI 界面如下图所示,图中不同的 Http 请求使用了不同的颜色进行标识,你甚至可以在UI上直接测试不同的 api 接口。
# 在 Action 方法上创建xml注解
到目前为止一切顺利,在刚才生成的 swagger 文档中,并没有看到 5 个 api 接口的任何注解,这就不优雅了,如果想要在 swagger 文档上增加 xml 注解,简单粗暴的做法可以直接在 Controller.Action 顶部写上注解信息。
接下来在 ValuesController 下的每一个 Action 上都加上注解,下面就是修改后的 ValueController。
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
///
/// Get action method without any argument
///
///
[HttpGet]
public ActionResult> Get()
{
return new string[] { "value1", "value2" };
}
///
/// Get action method that accepts an integer as an argument
///
///
///
[HttpGet("{id}")]
public ActionResult Get(int id)
{
return "value";
}
///
/// Post action method to add data
///
///
[HttpPost]
public void Post([FromBody] string value)
{
}
///
/// Put action method to modify data
///
///
///
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}
///
/// Delete action method
///
///
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# 打开 xml 注解
值得注意的是: Swagger 默认并不会显示 XML 注解,需要手工打开它,那怎么做呢?右键 Project,选择 Properties 后切换到 Build 页面,然后选中 XML documentation file
项 并且指定好 xml 生成的位置,参考如下:
接下来还要在 ConfigureServices 方法下将生成xml 的路径配置到 swagger 中,如下代码所示:
c.IncludeXmlComments(@"D:\Projects\IDG\IDGSwaggerDemo\IDGSwaggerDemo\IDGSwaggerDemo.xml");
这就是打开 Swagger 中的 xml 注解 所需的所有事情。
# 指定启动url 到 Swagger UI
要想将启动项目的url指到 SwaggerUI,右键 Project 并选择 Properties,在 Debug 的 Lanuch browser 上指定 swagger 即可,如下图所示:
再次运行程序可以发现默认页就是 Swagger URL 了,如下图所示:
从图中可以看到,5个API方法后面都有相应的 xml 注解了。
Swashbuckle 是一个非常好的工具,可以简单粗暴的给 API接口生成文档,从文中也可以看出 Swashbuckle 的配置非常简单,Swagger 还有一些更高级的功能,比如通过 CSS 来定制 Swagger UI,还可以根据API的版本生成不同的 Swagger 文
# 注解格式
寻找[Route(
代码,定义为[HttpGet]
或[HttpPost]
:
/// <summary>
/// 全局错误提示
/// </summary>
/// <remarks>用于系统的错误页提示返回信息。</remarks>
/// <returns>成功返回!</returns>
/// <param name="code">错误代码</param>
/// <returns></returns>
[Route("Common/Error/{code}")]
[HttpGet]
public IActionResult Error(int code)
{
//int code = DataConvert.CLng(GetParam("code"));
ViewBag.statusCode = code;
return View("~/Views/Shared/Prompt/statusCode.cshtml");
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 相关资料
- .NET CORE Swagger的使用,写好注释就是写好接口文档 https://www.toutiao.com/i6974963927478321668
- ASP.NET Core 使用Swagger https://www.cnblogs.com/vic-tory/p/12713378.html
- 如何在 ASP.Net Core 中使用 Swagger https://www.imooc.com/article/314826