一、开发环境
开发工具:Visual Studio 2022
工程模板:ASP.Net Core 8 Web API工程(官方标准的)
.Net环境:.Net Core 8.0
NuGet依赖:Swashbuckle.AspNetCore 6.9.0(UI用的默认的UI界面,
可以自由选择其他的UI界面)
二、基本概述
参考了网上很多大佬的帖子,实现基本就两种:
1、用自定义Attribute标注Controller,然后反射读取GroupInfo添加到SwaggerDoc
2、配置文件配置GroupInfo,然后读取配置添加到SwaggerDoc
这里用了第一种实现。
三、代码实现
1、自定义Attribute,这里自定义了三个Attribute
using Microsoft.AspNetCore.Mvc.ApiExplorer;
//用于标注的Attribute
namespace com.online.admin.apigroup
{
public class ApiGroupAttribute : Attribute, IApiDescriptionGroupNameProvider
{
public ApiGroupAttribute(ApiGroupNames name)
{
GroupName = name.ToString();
}
public string GroupName { get; set; }
}
}
//用于绑定分组信息的Attribute,这里就定义了一个,你可以多定义几个,用于不同模块
namespace com.online.admin.apigroup
{
public enum ApiGroupNames
{
[GroupInfo(Title = "账号管理",
ModuleName="Account",
Sort=1,Description = "账号管理",
Version = "v1")]
Account
}
}
//用于定义分组信息的Attribute
namespace com.online.admin.apigroup
{
public class GroupInfoAttribute : Attribute
{
public string Title { get; set; }
public string Version { get; set; }
public string Description { get; set; }
public string ModuleName { get; set; }
}
}
2、配置Swagger
这里是用的扩展方法去做配置的,也可以直接在Program.cs里直接配置,但是显得不是很优雅。
using com.online.admin.apigroup;
using Microsoft.OpenApi.Models;
using System.Reflection;
namespace com.online.admin.config
{
/// <summary>
/// SwaggerUI自定义扩展
/// </summary>
public static class SwaggerExtensions
{
public static IServiceCollection AddCustomSwagger(this IServiceCollection services)
{
services.AddSwaggerGen(options =>
{
var apiAssembly = Assembly.GetExecutingAssembly();
var apiDescriptions = apiAssembly.GetTypes()
.Where(t => t.GetCustomAttributes<ApiGroupAttribute>().Any())
.Select(t => t.GetCustomAttribute<ApiGroupAttribute>())
.Distinct();
foreach (var desc in apiDescriptions)
{
if (desc != null)
{
var groupText = desc.GroupName;
Type enumType = typeof(ApiGroupNames);
if (enumType==null) {
continue;
}
var field = enumType.GetField(groupText);
if (field == null) {
continue ;
}
var groupInfo = field.GetCustomAttribute<GroupInfoAttribute>();
if (groupInfo == null)
{
continue;
}
options.SwaggerDoc($"{groupInfo.ModuleName}", new OpenApiInfo
{
Title = $"{groupInfo.Title} API",
Version = string.IsNullOrEmpty(groupInfo.Version)?string.Empty:groupInfo.Version,
Description = groupInfo.Description,
});
}
}
options.SwaggerDoc("NoGroup", new OpenApiInfo
{
Title = "无分组"
});
options.DocInclusionPredicate((docName, apiDescription) =>
{
if (docName == "NoGroup")
{
return string.IsNullOrEmpty(apiDescription.GroupName);
}
else
{
return apiDescription.GroupName == docName;
}
});
});
return services;
}
public static IApplicationBuilder UseCustomSwagger(this WebApplication app)
{
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI(options =>
{
var apiAssembly = Assembly.GetExecutingAssembly();
var apiDescriptions = apiAssembly.GetTypes()
.Where(t => t.GetCustomAttributes<ApiGroupAttribute>().Any())
.Select(t => t.GetCustomAttribute<ApiGroupAttribute>())
.Distinct();
foreach (var desc in apiDescriptions)
{
if (desc != null)
{
var groupText = desc.GroupName;
Type enumType = typeof(ApiGroupNames);
var field = enumType.GetField(groupText);
var groupInfo = field?.GetCustomAttribute<GroupInfoAttribute>();
if (groupInfo == null)
{
continue;
}
options.SwaggerEndpoint($"/swagger/{groupInfo.ModuleName}/swagger.json", $"{groupInfo.Title} API");
}
}
options.SwaggerEndpoint("/swagger/NoGroup/swagger.json", "无分组");
//这里配置了取消swagger前缀,启动打开是提示找不到页面的
//直接访问项目ip+端口就能转到Swgger UI的界面了
options.RoutePrefix = string.Empty;
});
}
return app;
}
}
}
3、准备测试的Web API
注意 Web API里不要有Route相同的方法,不然会报错,文档显示不出来,这个被坑了好久,吃屎一般的感觉。
using com.online.admin.model.bo;
using com.online.admin.result;
using com.online.admin.service;
using Microsoft.AspNetCore.Mvc;
using com.online.admin.model.dto;
using NLog;
using com.online.admin.apigroup;
namespace com.online.admin.controller
{
[ApiGroup(ApiGroupNames.Account)]//顺序无所谓
[Route("api/[controller]/[action]")]
[ApiController]
public class AccountController : ControllerBase
{
private static readonly NLog.ILogger logger = LogManager.GetCurrentClassLogger();
public readonly IAccountService stockRecordService;
public AccountController(IAccountService stockRecordService)
{
this.stockRecordService = stockRecordService;
}
[HttpGet("{pageNum}")]
public async Task<IResult<PageInfo<Account>>> GetPage([FromBody] Query query, int pageNum, int pageSize)
{
PageInfo<Account> data = await stockRecordService.GetPageListAsync(null, pageNum, pageSize);
return ResultUtils<PageInfo<Account>>.SUCCESS(data);
}
[HttpGet("{id}")]
public async Task<IResult<Account>> Get(int id)
{
Account data = await stockRecordService.GetByIdAsync<int>(id);
return ResultUtils<Account>.SUCCESS(data);
}
[HttpPost]
public async Task<IResult<Account>> Post([FromBody] AccountDto dto)
{
return ResultUtils<Account>.SUCCESS();
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <param name="dto"></param>
/// <returns></returns>
[HttpPut("{id}")]
public async Task<IResult<Account>> Put(int id, [FromBody] AccountDto dto)
{
return ResultUtils<Account>.SUCCESS();
}
/// <summary>
///
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpDelete("{id}")]
public async Task<IResult<Account>> Delete(int id)
{
int Count = await stockRecordService.DeleteAsync<int>(id);
return ResultUtils<Account>.SUCCESS();
}
}
}
标签:Core,ASP,groupInfo,Web,admin,var,using,com,public
From: https://www.cnblogs.com/sitepoint/p/18510101