一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。
Swagger只是一个规范,不是一个实现!他的正式名称是OpenAPI
先把程序跑起来,直接上手
引入包:Swashbuckle.AspNetCore
在Startup.cs文件中配置并启动服务
在 ConfigureServices 类中配置服务(注入容器)
//引入 OpenApiInfo 的命名空间
using Microsoft.OpenApi.Models;
services.AddSwaggerGen(x =>
{
x.SwaggerDoc("v1", new OpenApiInfo() { Title = "Web Api", Version = "v1" });
});
如果安装的 Swashbuckle.AspNetCore Nuget包版本<= 3.0.0,写法略有不同
services.AddSwaggerGen(x =>
{
x.SwaggerDoc("v1", new Info() { Title = "Web Api", Version = "v1" });
});
将 OpenApiInfo 替换成 Info 即可 // 正式名称叫OpenAPI ....
在Configure 类中启动http中间件(响应请求)
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();//开发时可以直接暴露错误堆栈信息
#region swagger
app.UseSwagger();
app.UseSwaggerUI(x =>
{
x.SwaggerEndpoint("/swagger/v1/swagger.json", "Web App V1");
});
#endregion
}
之所以写到这个if语句中,是因为Swagger文档只用于开发环境中,方便前后端人员交流使用,一旦项目处于生产阶段,这个文档也就废弃了。
启动项目
修改url,在端口号后面添加 /swagger ,然后 回车键 即可
OK,到这里,基本功能完成,可以使用了!
会用了还不够,要用好,丰富细节
丰富内容清单
- 版本信息可以再详细点
- api方法添加中文注释
- 启动项目直接进入到 swagger 文档页面
- Models添加 限制/注解 信息,让字段信息更丰富
- .....
new OpenApiInfo()添加其他信息
查看源码看看有多少属性
namespace Microsoft.OpenApi.Models
{
public class OpenApiInfo : Object, IOpenApiSerializable, IOpenApiElement, IOpenApiExtensible
{
public String Title
public String Description
public String Version
public Uri TermsOfService
public OpenApiContact Contact
public OpenApiLicense License
public IDictionary<String, IOpenApiExtension> Extensions
添加属性后代码:
services.AddSwaggerGen(x =>
{
x.SwaggerDoc("v1", new OpenApiInfo()
{
Title = "Web Api",
Version = "v1",
Description = "Web Api 版本v1的描述信息",
TermsOfService = new System.Uri("http://www.bilibili.com"), // 服务条款
Contact = new OpenApiContact // 联系信息
{
Email = "123456@sina.com",
Name = "张三",
Url = new System.Uri("http://www.taobao.com")
},
License = new OpenApiLicense
{
Name = "开放APi许可证",
Url = new Uri("http://www.sina.com")
}
});
});
UI效果:
api方法添加中文注释
给api方法或接口添加注释内容
在方法上一行连续按三次 / 即可
在指定文件夹中生成 .xml 文档
- 鼠标移到【解决方案资源管理器】的项目名称上,右键 点击 属性
- 选择 生成 勾选XML 文档文件(X)
- 修改为相对路径,到项目的App_Data 文件夹中
再次运行项目后,该 .xml会自动 生成/更新
在 [生成xml文件] 这一步执行完之后,只要是方法/控制器等,如果没有添加注释信息,IDE就会报 警告 级别的错误
解决办法:左侧错误代码添加到项目配置中
此时警告级别错误 该类型的没有了
导入文档
在 services.AddSwaggerGen 中 添加如下代码
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"; //获取文档
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile); // 获取文档路径
x.IncludeXmlComments(xmlPath); // 导入注释内容
拆开来写
var xmlName = Assembly.GetExecutingAssembly().GetName().Name; // 获取当前执行程序名称
var xmlFile = $"{xmlName}.xml"; //获取xml文档名称
var basePath = AppContext.BaseDirectory; // 获取项目路径,到bin/debug里面
var xmlPath = Path.Combine(basePath, xmlFile);
x.IncludeXmlComments(xmlPath); // 导入注释内容
因为xml文档名称是已知的,所以还可以简化写法
var basePath = AppContext.BaseDirectory; // 获取项目路径,到bin/debug里面
var xmlPath = Path.Combine(basePath, "blogV330.xml");
x.IncludeXmlComments(xmlPath); // 导入注释内容
试想:如果我的xml文档名称和程序名称不一样,那上面第一种方法就不可行了,而是直接根据生成名称来写进去,虽然缺少了灵活性,但是不会错
完成代码块:
services.AddSwaggerGen(x =>
{
x.SwaggerDoc("v1", new OpenApiInfo()
{
Title = "Web Api",
Version = "v1",
Description = "Web Api说明文档",
TermsOfService = new System.Uri("http://www.bilibili.com"), // 服务条款
Contact = new OpenApiContact // 联系信息
{
Email = "123456@sina.com",
Name = "zhangping",
Url = new System.Uri("http://www.taobao.com")
},
});
var basePath = AppContext.BaseDirectory; // 获取项目路径,到bin/debug里面
var xmlPath = Path.Combine(basePath, "blogV330.xml");
x.IncludeXmlComments(xmlPath); // 导入注释内容
});
效果展示
控制器添加注释
上图中 WeatherForecast 并没有注释内容
- 只需要添加一个 true 即可,上面不写,默认是 false
- 当然,控制器上面也要有注释,不然都是白搭
- 效果
原理解析:查看 IncludeXmlComments 源码
- 可见这个方法还有一个参数配置,见词知意,包含控制器xml注释,默认是false
- 那只需修改为true即可!
启动项目直接进入到 swagger 文档页面
两步即可
- Configure 中添加 RoutePrefix 信息
配置为空表示直接在根域名(localhost:53952)访问该文件(swagger.json)
- launchSettings.json中在启动方式中将launchUrl属性改成空字符串 或者 直接删掉 launchUrl 选项
运行即可直接进入到swagger文档界面,此时url如下
Models添加 限制/注解 信息,让字段信息更丰富
-
先展示出来,然后再考虑如何丰富注释
-
对api方法的隐藏(不想展示出来时的做法)
新建Model并展示注释说明
- 解决方案中新建 .net standard 类库项目
- 创建实体类Article
using System;
using System.Collections.Generic;
using System.Text;
namespace blog.Models
{
/// <summary>
/// 文章
/// </summary>
public class Article
{
/// <summary>
/// id
/// </summary>
public Guid Id { get; set; }
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 作者
/// </summary>
public string Author { get; set; }
/// <summary>
/// 类别
/// </summary>
public string Category { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public DateTime CreateTime { get; set; }
/// <summary>
/// 删除状态
/// </summary>
public bool IsDelete { get; set; } = false;
}
}
- 在blogV330项目中引用类库项目
依赖项--右键-->添加引用
选中类库 并确认
效果
- 在blog.Models项目中配置生成 .xml 文件
- 在Startup.cs中导入注释内容
- 在blogV330项目中添加控制器 ArticleController
using blog.Models;
using Microsoft.AspNetCore.Mvc;
namespace blogV330.Controllers
{
/// <summary>
/// 文章Api
/// </summary>
[ApiController]
[Route("[controller]/[action]")]
public class ArticleController : ControllerBase
{
/// <summary>
/// post请求
/// </summary>
/// <param name="article"></param>
[HttpPost]
public void Post(Article article)
{
}
}
}
最少添加一个方法,否则swagger文档不会显示models和控制器
效果
隐藏控制器或方法,使其不在swagger文档中展现
方案:
- 在控制器或者方法上添加特性: [ApiExplorerSettings(IgnoreApi =true)]
- 控制器或方法的修饰符改成 private
[HttpGet]
[Route("get1")]
public void Get1()
{
}
[HttpGet]
[Route("get2")]
private void Get2()
{
}
[HttpGet]
[Route("get3")]
[ApiExplorerSettings(IgnoreApi =true)]
public void Get3()
{
}
- 效果
如上:get2和get3都没有展现出来
给api方法添加 响应类型 描述
一个方法在被请求访问时,会有不同的响应类型,例如200表示成功,400表示失败,500表示服务器报错等等
- 修改前样式
- 修改后样式
具体做法:在方法上添加特性 ProducesResponseType, 在注释中添加 response 信息
若注释信息不添加,请求备注则会显示默认值,例如200 ---> Success , 400 ---> Bad Request 等
- 代码实现
/// <summary>
/// get1请求
/// </summary>
/// <response code="200">请求成功标志备注</response>
/// <response code="400">请求失败标志备注</response>
[HttpGet]
[Route("get1")]
[ProducesResponseType(typeof(Article), 200)]
[ProducesResponseType(400)]
public void Get1()
{
}
注:typeof(models) 参数可不写