第五十一节: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 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 
posted @ 2025-02-12 20:33  Yaopengfei  阅读(557)  评论(2)    收藏  举报