使用Swashbuckle为不同API方法自定义请求Schema字段展示规则
实现方案
方案1:拆分请求DTO(最推荐)
这是最符合接口设计规范的实现方式,不同业务场景使用独立的请求传输对象,无需额外配置Swagger即可自动适配展示规则:
// Insert接口专用请求类 public class InsertMyObjectReq { public string Name { get; set; } } // Update接口专用请求类 public class UpdateMyObjectReq { public int ID { get; set; } public string Name { get; set; } }
将Insert接口的参数类型改为InsertMyObjectReq,Update接口的参数类型改为UpdateMyObjectReq即可,后续不同接口的参数校验、字段扩展也可以独立维护,耦合度更低。
方案2:自定义Swagger操作过滤器(不拆分原有实体类)
如果业务场景不允许拆分实体类,可以通过Swagger过滤器针对指定接口动态隐藏字段:
- 自定义过滤器实现类:
using Microsoft.OpenApi.Models; using Swashbuckle.AspNetCore.SwaggerGen; public class HideIdForInsertFilter : IOperationFilter { public void Apply(OpenApiOperation operation, OperationFilterContext context) { // 匹配Insert接口,可根据实际接口命名/路由规则调整判断条件 if (context.MethodInfo.Name.Equals("Insert", StringComparison.OrdinalIgnoreCase) || context.ApiDescription.RelativePath?.Contains("Insert", StringComparison.OrdinalIgnoreCase) == true) { // 移除请求体JSON Schema中的ID字段 if (operation.RequestBody?.Content.TryGetValue("application/json", out var mediaType) == true) { // 如果Swagger关闭了驼峰命名转换,此处改为"ID" mediaType.Schema.Properties.Remove("id"); } } } }
- 在Swagger配置中注册过滤器(Program.cs):
builder.Services.AddSwaggerGen(opt => { // 原有Swagger配置保留 opt.OperationFilter<HideIdForInsertFilter>(); });
该方案仅修改Swagger文档的展示效果,不会影响实际接口的参数接收逻辑。
方案3:条件序列化(同时控制文档展示和实际参数处理)
如果需要Insert接口不仅在文档中隐藏ID,实际接收参数时也忽略传入的ID值,可以使用序列化框架的条件序列化特性:
public class MyObject { public int ID { get; set; } public string Name { get; set; } // Newtonsoft.Json 约定方法,返回false时序列化/反序列化都会忽略ID字段 public bool ShouldSerializeID() { var context = new HttpContextAccessor().HttpContext; if (context == null) return true; // 根据当前请求的路径判断是否为Insert接口 return !context.Request.Path.Value.Contains("Insert", StringComparison.OrdinalIgnoreCase); } }
使用该方案需要先在Program.cs中注册IHttpContextAccessor:
builder.Services.AddHttpContextAccessor();
内容的提问来源于stack exchange,提问作者Aleksa Ristic
相关产品推荐
相关产品推荐

