首页 > 编程语言 >ASP.Net Core 8 Web API整合Swagger UI并进行模块分组吃屎般瞬间记录

ASP.Net Core 8 Web API整合Swagger UI并进行模块分组吃屎般瞬间记录

时间:2024-10-28 11:58:59浏览次数:5  
标签:Core ASP groupInfo Web admin var using com public

一、开发环境

开发工具: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

相关文章