.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
相关产品推荐
相关产品推荐

