在 swagger 中支持 asp.net core 可选路由参数

场景

  • 同一个 Controller 可能对不同环境有不同的行为,通过路由的 env 参数调整注入的参数

  • 每一次请求上下文可能会根据 env 的值修改 repo 的具体参数

  • 系统会提供默认的 env, 因此此处的路由参数为可选参数

  • swagger 根据 OpenApi v3.x 规范,即使使用 ? 标注为可选,ui 中仍然为 required

    C# 复制代码
    [Route("api/{env:env?}/[controller]")]
    [ApiController]
    public class DemoController(IDemoRepo repo) : ControllerBase
    {
        /* other codes */
    }

解决方法

  • 增加自定的方法修改已经生成的 swagger 文档
C# 复制代码
builder.Services.AddSwaggerGen(opt =>
{
   opt.OperationFilter<ApplyOptionalRouteParameterOperationFilter>();
   /* other codes */
}

public partial class ApplyOptionalRouteParameterOperationFilter : IOperationFilter
{
   public void Apply(OpenApiOperation operation, OperationFilterContext context)
   {
       if (operation.Parameters.Count == 0) return;
       // 获取方法以及类上面的 RouteAttribute
       var attrs = context.MethodInfo.GetCustomAttributes(true)
           .Concat(context.MethodInfo.DeclaringType?.GetCustomAttributes(true) ?? [])
           .OfType<RouteAttribute>().Where(x => x.Template.Contains('?')).ToList();
           
       // 遍历所有 RouteAttribute,如果包含可选参数,则对应修改 OpenAPI 参数定义
       foreach (var route in attrs)
       {
           var matches = RouteTemplateRegex().Matches(route.Template);
           foreach (Match match in matches)
           {
               var name = match.Groups["name"].Value;
               var parameter = operation.Parameters.FirstOrDefault(x => x.Name == name);
               if (parameter is not null)
               {
                   parameter.AllowEmptyValue = true;
                   parameter.Required = false;
                   parameter.Schema.Nullable = true;
               }
           }
       }
   }

   [GeneratedRegex(@"\{(?<name>\w+)(\:\w+)*\?\}")]
   private static partial Regex RouteTemplateRegex();
}
相关推荐
深蓝AI5 分钟前
Python 3.13 的 Queue.shutdown:异步消费者终于能正常收工了
后端
武子康42 分钟前
MultiNet6 空闲崩溃:`EXCVADDR=0x8` 后又出现 `CORRUPT HEAP`
人工智能·后端·agent
武子康2 小时前
MultiNet7 每轮都 clean,ESP32-P4 内存为什么还在掉?
人工智能·后端·agent
超级架构师2 小时前
PRAXO-CORE 2.5.0:用 conformance 和显式边界构建 Go Agent 框架
开发语言·人工智能·后端·golang·ai编程·智能体框架·praxo-core
陈随易3 小时前
AI 运维服务器,安全又可靠的方法
前端·后端·程序员
IT_陈寒4 小时前
JavaScript的this坑人实录,这次我真的记下来了
前端·人工智能·后端
starzy19905 小时前
Scala类和对象:从构造器到样例类的完整指南
开发语言·后端·scala
梦影_5 小时前
MySQL进阶教程(五)—— SQL调优(下)
android·大数据·数据库·后端·sql·mysql·database
考虑考虑5 小时前
mariadb数据库
数据库·后端·mariadb
明月_清风6 小时前
用自然语言操控真机:Google Artemis 移动端 AI Agent 上手与实践
人工智能·后端