如何在Swagger UI中隐藏FormData的部分属性(含导航属性)
解决FormData请求中嵌套导航属性在Swagger UI中隐藏的问题
方案一:自定义标记属性+Schema过滤器(推荐,灵活可控)
1. 创建忽略标记属性
定义一个特性,用于标记需要在Swagger中隐藏的属性:
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] public class SwaggerIgnoreAttribute : Attribute { }
2. 标记需要隐藏的属性
在请求基类的导航属性上添加该标记:
public abstract class RequestCommand { [SwaggerIgnore] public LoggedUser User{ get; init; } // 其他业务属性... }
3. 编写Schema过滤器实现递归过滤
实现ISchemaFilter接口,递归遍历所有属性(包括嵌套对象),移除标记了[SwaggerIgnore]的属性对应的Swagger Schema:
public class SwaggerIgnoreFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { if (schema.Properties == null || context.Type == null) return; // 过滤当前类型下标记了忽略的属性 var ignoreProps = context.Type.GetProperties() .Where(p => p.GetCustomAttribute<SwaggerIgnoreAttribute>() != null) .Select(p => p.Name) .ToList(); foreach (var propName in ignoreProps) { schema.Properties.Remove(propName); } // 递归处理嵌套对象的属性 foreach (var property in schema.Properties.Values) { if (property.Type == "object" && property.Properties != null) { var nestedProp = context.Type.GetProperties() .FirstOrDefault(p => p.Name.Equals(property.Name, StringComparison.OrdinalIgnoreCase)); if (nestedProp != null) { Apply(property, new SchemaFilterContext(nestedProp.PropertyType, context.SchemaRepository, context.Annotations)); } } } } }
4. 注册过滤器到Swagger配置
在项目的Swagger服务配置中添加这个过滤器:
builder.Services.AddSwaggerGen(c => { c.SchemaFilter<SwaggerIgnoreFilter>(); // 其他Swagger配置项... });
方案二:直接指定类型过滤(无需自定义属性)
如果不需要灵活标记,可直接在过滤器中指定要隐藏的属性类型(比如LoggedUser):
public class SwaggerIgnoreFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { if (schema.Properties == null || context.Type == null) return; // 移除所有类型为LoggedUser的属性 var removeProps = schema.Properties .Where(kv => context.Type.GetProperty(kv.Key)?.PropertyType == typeof(LoggedUser)) .Select(kv => kv.Key) .ToList(); foreach (var propName in removeProps) { schema.Properties.Remove(propName); } // 递归处理嵌套属性(同方案一) foreach (var property in schema.Properties.Values) { if (property.Type == "object" && property.Properties != null) { var nestedProp = context.Type.GetProperties() .FirstOrDefault(p => p.Name.Equals(property.Name, StringComparison.OrdinalIgnoreCase)); if (nestedProp != null) { Apply(property, new SchemaFilterContext(nestedProp.PropertyType, context.SchemaRepository, context.Annotations)); } } } } }
同样需要在Swagger配置中注册该过滤器。
为什么之前的方案无效?
常规的FormData忽略方案大多只处理顶层属性,没有递归处理嵌套对象。Swagger在生成FormData的Schema时,会将嵌套对象拆分为User.Id、User.Name这类扁平化字段,只有递归过滤整个嵌套对象的Schema,才能彻底隐藏这些子属性。
内容的提问来源于stack exchange,提问作者FeGo
相关产品推荐
相关产品推荐

