You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Swashbuckle:保留签名时文档化可选查询参数并支持测试

解决方案

我完全理解你的核心诉求:既要保持回调端点的签名不动,又要在Swagger UI里只展示部分关键查询参数,同时还得保留对所有参数的测试能力(包括没文档化的那些)。结合Swashbuckle的特性,我们可以通过模型属性标记+自定义Swagger过滤器来实现,具体步骤如下:

1. 先理清楚参数绑定的基础结构

既然有100+可选查询参数,你肯定是用一个复杂模型来绑定这些参数(总不可能把100个参数都写在方法签名里)。假设你的message参数对应的模型是这样的:

public class CallbackMessage
{
    // 需要重点文档化的核心参数
    public string TransactionId { get; set; }
    public int ExecutionStatus { get; set; }
    
    // 其他100+可选参数(无需在Swagger里展示)
    public string OptionalTraceId { get; set; }
    public DateTime? Timestamp { get; set; }
    // ... 更多属性
}

你的端点签名应该类似这样:

/// <summary>
/// Callback Endpoint
/// </summary>
/// <returns>HTTP 200 <see cref="HttpStatusCode.OK"/>.</returns>
/// <param name="message">The message containing all query parameters</param>
[HttpGet("callback")]
public IActionResult Callback([FromQuery] CallbackMessage message)
{
    // 业务逻辑处理
    return Ok();
}

2. 标记需要展示的参数

给模型里需要在Swagger UI中显示的属性添加[SwaggerSchema]注解,同时给不需要展示的属性标记Hidden:

using Swashbuckle.AspNetCore.Annotations;

public class CallbackMessage
{
    [SwaggerSchema(Description = "唯一标识回调对应的业务交易ID")]
    public string TransactionId { get; set; }

    [SwaggerSchema(Description = "交易执行状态码,0表示成功,非0表示失败")]
    public int ExecutionStatus { get; set; }

    [SwaggerSchema(Hidden = true)]
    public string OptionalTraceId { get; set; }

    [SwaggerSchema(Hidden = true)]
    public DateTime? Timestamp { get; set; }
    // ... 其他需要隐藏的属性
}

如果你不想逐个标记隐藏属性,也可以反过来:只给需要展示的属性加注解,后续用过滤器筛选这些属性。

3. 自定义Swagger过滤器控制文档显示

创建一个IOperationFilter,用来过滤Swagger文档里的参数,只保留我们标记的核心参数:

using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Linq;

public class FilterCallbackQueryParamsFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        // 定位到你的回调端点(可以通过路由、Action名称判断,这里用Action名称举例)
        var isCallbackEndpoint = context.ApiDescription.ActionDescriptor.DisplayName.Contains("Callback");
        if (!isCallbackEndpoint) return;

        // 过滤掉message参数中被标记为Hidden的属性
        var messageParams = operation.Parameters.Where(p => p.Name.StartsWith("message.")).ToList();
        foreach (var param in messageParams.ToList())
        {
            // 提取属性名,比如从"message.TransactionId"中拿到"TransactionId"
            var propertyName = param.Name.Split('.')[1];
            // 获取该属性的Swagger注解
            var propertyAttr = context.ApiDescription.ParameterDescriptions
                .FirstOrDefault(pd => pd.Name == propertyName)?.ParameterInfo?.GetCustomAttributes(true)
                .OfType<SwaggerSchemaAttribute>()
                .FirstOrDefault();

            // 如果属性被标记为Hidden,就从Swagger文档中移除这个参数
            if (propertyAttr?.Hidden == true)
            {
                operation.Parameters.Remove(param);
            }
        }
    }
}

4. 把过滤器注册到Swashbuckle配置中

在Program.cs(或Startup.cs)的Swagger配置里添加这个过滤器:

builder.Services.AddSwaggerGen(c =>
{
    // 启用Swagger注解支持
    c.EnableAnnotations();
    
    // 注册自定义过滤器
    c.OperationFilter<FilterCallbackQueryParamsFilter>();

    // 其他Swagger基础配置
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
});

5. 验证最终效果

  • Swagger UI里只会展示你标记的TransactionId和ExecutionStatus参数,界面简洁清晰;
  • 如果你需要测试未文档化的参数,直接在请求URL末尾手动添加即可(比如/callback?TransactionId=123&OptionalTraceId=abc),端点依然能正常接收并绑定这些参数;
  • 端点的签名完全保持不变,完全符合你的要求。

内容的提问来源于stack exchange,提问作者Neuronetic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:18:00