如何从SwaggerResponse模型中隐藏/排除属性?仅针对响应
解决Swagger Response模型中排除指定属性的问题
问题场景
需要从Swagger的Response模型中排除Dependency类的VersionRange属性,同时保留该属性的序列化/反序列化能力——不能用protected/internal修饰符,也不能用[JsonIgnore]特性。已尝试实现ISchemaFilter但未生效:
public class Dependency { public string Name { get; set; } [JsonConverter(typeof(VersionRangeConverter))] [SwaggerExclude] public VersionRange VersionRange { get; set; } }
public class SwaggerExcludeFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { if (schema?.Properties == null) { return; } var properties = context?.Type?.GetProperties().Where(x => x.GetCustomAttribute<SwaggerExcludeAttribute>() != null); foreach (PropertyInfo prop in properties ?? Enumerable.Empty<PropertyInfo>()) { if (schema.Properties.ContainsKey(prop.Name)) { schema.Properties.Remove(prop.Name); } } } }
问题原因
原过滤器失效的核心原因:Swagger默认会将C#的PascalCase属性名转换为JSON的camelCase(比如VersionRange变成versionRange),但代码直接用prop.Name(PascalCase格式)去匹配schema.Properties中的键(camelCase格式),导致找不到对应属性,无法完成移除操作。
解决方案
1. 确保自定义特性正确定义
先确认SwaggerExcludeAttribute已正确实现:
[AttributeUsage(AttributeTargets.Property)] public class SwaggerExcludeAttribute : Attribute { }
2. 修正ISchemaFilter逻辑
修改过滤器逻辑,适配Swagger的属性命名规则,同时兼容[JsonPropertyName]特性指定的自定义名称:
public class SwaggerExcludeFilter : ISchemaFilter { public void Apply(OpenApiSchema schema, SchemaFilterContext context) { if (schema?.Properties == null || context.Type == null) return; // 获取所有标记了SwaggerExclude的属性 var excludedProperties = context.Type.GetProperties() .Where(prop => prop.GetCustomAttribute<SwaggerExcludeAttribute>() != null); foreach (var prop in excludedProperties) { // 获取Swagger中实际使用的属性名 string targetPropertyName; // 优先使用JsonPropertyName指定的名称 var jsonPropAttr = prop.GetCustomAttribute<JsonPropertyNameAttribute>(); if (jsonPropAttr != null) { targetPropertyName = jsonPropAttr.Name; } // 否则转换为默认的camelCase else { targetPropertyName = char.ToLowerInvariant(prop.Name[0]) + prop.Name.Substring(1); } // 移除对应属性 if (schema.Properties.ContainsKey(targetPropertyName)) { schema.Properties.Remove(targetPropertyName); } } } }
3. 注册过滤器
在Swagger配置中确保已注册该过滤器:
// Program.cs 或 Startup.cs builder.Services.AddSwaggerGen(c => { // 注册自定义Schema过滤器 c.SchemaFilter<SwaggerExcludeFilter>(); });
验证
启动项目后查看Swagger文档,Dependency模型的Response定义中VersionRange属性已被排除,同时该属性依然正常参与JSON的序列化和反序列化。
内容的提问来源于stack exchange,提问作者S2K
相关产品推荐
相关产品推荐

