惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Jina AI
Jina AI
Apple Machine Learning Research
Apple Machine Learning Research
宝玉的分享
宝玉的分享
M
MIT News - Artificial intelligence
S
SegmentFault 最新的问题
博客园 - 叶小钗
量子位
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - Franky
博客园 - 司徒正美
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
人人都是产品经理
人人都是产品经理
Hugging Face - Blog
Hugging Face - Blog
V
Visual Studio Blog
阮一峰的网络日志
阮一峰的网络日志
博客园 - 【当耐特】
Google DeepMind News
Google DeepMind News
L
LangChain Blog
Stack Overflow Blog
Stack Overflow Blog
博客园_首页
U
Unit 42
月光博客
月光博客
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC

博客园 - 郎中令

锦衣夜行,AI乐园 Redis实战:用缓存为数据库减负(二) Redis初体验: 搭建与简单应用(一) 真实性编码:配置NLog日志+Seq分布式 防御性编码:手搓NLog日志+Seq分布式 对接Java所谓的DES加解密 人大金仓数据库转换 人大金仓踩坑指南 RSA加解密笔记 HTTPS请求笔记- SSL安全通道验证问题 .NetCore打包部署(DLL) 字典映射处理 SM4算法快速预览与Framework4.5版本对接 简易首页防暴力-字典计时器 vite运行打包前端-部署Linux 记一次线上数据库异常的协助排查 降本增笑:记一次首页并发白屏优化过程 solr 基础介绍以及踩坑日记 动态展示缩放背景图
.Net Core的SwaggerUI接口分类+固定路由
郎中令 · 2025-09-01 · via 博客园 - 郎中令

      随着.Net Core 的逐步普及,  越来越多系统采用前后端分离的方式进行团队开发,随着业务的逐步积累,我们的接口更是五花八门,路由乱七八糟,不容易维护,今天研究一下Swagger,浅浅的记录一下路由+业务拆分,先贴一下最后的效果,可以看到,会根据不同的选择定义,展示对应的接口列表,并且路由都有固定的格式

image

 话不多说,开干,首先定义一个接口的业务类型枚举 SwaggerVersion

    public enum SwaggerVersion
    {
        Native,

        KiaserAPI,

        OtherAPI,
    }

然后创建 SwaagerAttribute 来上标记,  创建 SwaggerConvention 在启动时扫描标记 → 自动完成“分组 + 路由加版本前缀

    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
    public class SwagerAttribute : Attribute, IApiDescriptionGroupNameProvider
    {
        public string GroupName { get; }

        public SwagerAttribute(SwaggerVersion version)
        {
            GroupName = version.ToString(); 
        }
    }

    public class SwaggerConvention : IControllerModelConvention
    {
        public void Apply(ControllerModel controller)
        {
            var attr = controller.ControllerType.GetCustomAttributes<SwagerAttribute>(false).FirstOrDefault();
            if (attr == null) return;

            controller.ApiExplorer.GroupName = attr.GroupName;

            var prefix = $"/{attr.GroupName}/[controller]/[action]";
            foreach (var selector in controller.Selectors)
            {
                selector.AttributeRouteModel = selector.AttributeRouteModel == null ? new AttributeRouteModel { Template = prefix } : 
                    AttributeRouteModel.CombineAttributeRouteModel(new AttributeRouteModel { Template = prefix }, selector.AttributeRouteModel);
            }
        }
    }

这些都是准备工作,处理完毕之后,我们在Startup.cs 类注册的时候,绑定即可(注释部分)

            services.AddControllers(opt=> {
                //绑定路由自定义格式
                opt.Conventions.Add(new SwaggerConvention()); 
            });
            services.AddSwaggerGen(c =>
            {
                typeof(SwaggerVersion).GetEnumNames().ToList().ForEach(v =>
                {
                    var descriptionAttribute = (DescriptionAttribute)typeof(SwaggerVersion).GetField(v).GetCustomAttributes(typeof(DescriptionAttribute), false).FirstOrDefault();
                    string description = descriptionAttribute?.Description ?? v;

                    c.SwaggerDoc(v, new OpenApiInfo
                    {
                        Version = v,
                        Description = $"{description} 文档",
                        Title = description,
                    });
                });
                //绑定业务的下拉分组依赖
                c.DocInclusionPredicate((docName, apiDesc) =>
                {
                    var groupProvider = apiDesc.ActionDescriptor.EndpointMetadata
                        .OfType<IApiDescriptionGroupNameProvider>()
                        .FirstOrDefault();

                    return string.Equals(docName, groupProvider?.GroupName, StringComparison.OrdinalIgnoreCase);
                });

以上代码安全可靠,直接放心食用,简单加入条件之后,SwaggerUI 站点的业务接口清晰可见,方便筛选和维护