第五十一节:Core9.0中OpenApi自定义文档(Swagger 和 Scalar两种方式)
一. Swagger配置
(说明:core9.0中默认删除swagger配置,如果需要,需要自行安装,具体的写法和core8.0的写法有一些区别,下面以Asp.net Core MVC 9.0 为例,WebApi配置相同)
1. 安装程序集
通过Nuget安装【Swashbuckle.AspNetCore 7.3.2】,不需要 【Microsoft.AspNetCore.OpenApi】
2 忽略提示+生成配置文件
添加最后两行代码
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<!--<Nullable>enable</Nullable>-->
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>_02_WebApi_Scalar</RootNamespace>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

3 新增Swagger配置
包括:基本的配置、支持注释、配置区域分组、支持JWT传递
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
//1.支持注释
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"{Assembly.GetExecutingAssembly().GetName().Name}.xml"));
//2.配置分组显示
options.SwaggerDoc("Main", new OpenApiInfo { Version = "V1.0", Title = "主模块", Description = "按区域分组管理,右上角切换", });
options.SwaggerDoc("AdminApi_Areas", new OpenApiInfo { Version = "V1.0", Title = "AdminApi_Areas模块" });
options.DocInclusionPredicate((docName, apiDes) =>
{
if (!apiDes.TryGetMethodInfo(out var method)) return false;
// 同时获取控制器和动作上的 ApiExplorerSettingsAttribute 特性中的 GroupName
var groupNames = method.DeclaringType.GetCustomAttributes(true).OfType<ApiExplorerSettingsAttribute>().Select(m => m.GroupName)
.Concat(method.GetCustomAttributes(true).OfType<ApiExplorerSettingsAttribute>().Select(m => m.GroupName));
// 如果文档名为 Main 且没有指定分组,则包含该 API
if (docName == "Main" && !groupNames.Any()) return true;
// 检查是否有匹配的分组名
return groupNames.Contains(docName);
});
//3. 支持JWT传递
var scheme = new OpenApiSecurityScheme()
{
Description = "普通的jwt校验, 即:说白了就是在Header中传递参数的时候多了一个:auth=token",
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "auth" },
Scheme = "oauth2",
Name = "auth",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
};
options.AddSecurityDefinition("auth", scheme);
options.AddSecurityRequirement(new OpenApiSecurityRequirement { [scheme] = [] });
});
4. 管道配置
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/Main/swagger.json", "主模块");
options.SwaggerEndpoint("/swagger/AdminApi_Areas/swagger.json", "AdminApi_Areas");
options.DocExpansion(DocExpansion.List);//配置文档的展开形式:List列表(默认) None(折叠) Full(展开到参数级别)
});
5 代码配置
(1) 普通控制器中的代码
[Route("[controller]/[action]")]
public class DemoController : Controller
{
/// <summary>
/// 校验登录
/// </summary>
/// <param name="userName">账号</param>
/// <param name="pwd">密码</param>
/// <returns></returns>
[HttpPost]
public IActionResult Login(string userName, string pwd)
{
return Json(new { status = "ok", msg = "登录成功", data = new { userName, pwd } });
}
}
(2) 区域控制器中的代码
[Area("AdminApi_Areas")]
[Route("Api/[area]/[controller]/[action]")]
[ApiExplorerSettings(GroupName = "AdminApi_Areas")]
public class SysUserController : Controller
{
/// <summary>
/// 获取用户信息
/// </summary>
/// <returns></returns>
[HttpGet]
public string GetUserInfo()
{
return "获取成功";
}
}
6. 测试
访问地址:https://localhost:44352/swagger/index.html

补充:webapi9.0项目无法默认启动直接跳转到 xxxx/swagger/index.html页面,需要在管道位置配置下面代码。
app.Use(async (context, next) =>
{
if (context.Request.Path == "/" || context.Request.Path == "/index.html")
{
context.Response.Redirect("/swagger");
return;
}
await next();
});
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/Main/swagger.json", "主模块");
options.SwaggerEndpoint("/swagger/AdminApi_Areas/swagger.json", "AdminApi_Areas");
//配置文档的展开形式:List列表(默认) None(折叠) Full(展开到参数级别)
options.DocExpansion(DocExpansion.List);
//使webapi项目默认启动打开的是
options.RoutePrefix = "swagger";
});
二. Scalar配置
(说明:Core9.0后官方推荐用Scalar,但是个人非常不喜欢,下面以webapi9.0版本为例,演示基本用法)
1. 前提
需要安装【Microsoft.AspNetCore.OpenApi】, webApi9.0中默认包含,不需要单独添加。
2 安装程序集
安装 【Scalar.AspNetCore】
3 配置代码
(1) 注册服务
builder.Services.AddOpenApi(options =>
{
//修改主页面的介绍
options.AddDocumentTransformer((document,context,cancellationToken) =>
{
document.Info = new() { Title="测试Scalar",Version="V1",Description="介绍各种用法"};
return Task.CompletedTask;
});
});
(2) 管道配置
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
//scalar相关配置
app.MapScalarApiReference();
}
(3) 配置跨域
必须配置,否则测试请求无法访问
//允许跨域请求
app.UseCors(options =>
{
options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader().WithExposedHeaders("Content-Disposition");
});
4 代码配置
(1) 基础配置
A 控制器上必须加:[ApiController] 和 [Route("[controller]/[action]")]
B action必须加: [HttpPost]、 [HttpGet] 等等
(2) action分类
使用[Tags("xxx")]特性,可以直接添加在action或controller上。
ps:默认文档中是根据controller分类,加上了Tags,优先级更高,优先按照Tags分
(3) 注释问题
方法注释: [EndpointSummary("获取当前时间1")]
参数注释: 每个参数名前添加 [Description("用户名")]
PS:非常繁琐,个人不喜欢
[ApiController]
[Route("[controller]/[action]")]
public class HomeController : Controller
{
/// <summary>
/// 校验登录
/// </summary>
/// <param name="userName">用户名</param>
/// <param name="pwd">密码</param>
/// <returns></returns>
[HttpPost]
[EndpointSummary("校验登录")]
public IActionResult CheckLogin([Description("用户名")]string userName, [Description("密码")] string pwd)
{
return Json(new { status = "ok", msg = "登录成功", data = userName + "," + pwd });
}
}
Tag演示
[ApiController]
[Route("[controller]/[action]")]
public class GuideController : Controller
{
/// <summary>
/// 获取当前时间1
/// </summary>
/// <returns></returns>
[HttpGet]
[Tags("时间相关")]
[EndpointSummary("获取当前时间1")]
public string GetTime1()
{
return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
}
/// <summary>
/// 获取当前时间2
/// </summary>
/// <returns></returns>
[HttpPost]
[Tags("时间相关")]
public string GetTime2()
{
return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
}
/// <summary>
/// 获取当前时间1
/// </summary>
/// <returns></returns>
[HttpGet]
public string GetTime3()
{
return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
}
}
5 测试
访问地址: http://localhost:5159/scalar/v1

token传递

未完成:
区域内的不显示,无法分组
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。

浙公网安备 33010602011771号