ASP.NET Web API如何隐藏响应中值为null的嵌套类属性
问题场景
Web API返回响应时,需要自动将值为null的嵌套类属性从JSON结果中移除,当前模型定义如下:
public class School { public Student students {get; set;} public Teacher teachers {get; set;} } public class Student { public string id {get; set;} public string name {get; set;} } public class Teacher { public string id {get; set;} public string name {get; set;} }
未配置时,teachers为null的响应会携带teachers: null字段,预期是直接隐藏该字段。之前尝试添加[DataMember(EmitDefaultValues = False)]、[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]特性均未生效。
特性失效常见原因
- 序列化器和特性所属类库不匹配:比如.NET Core 3.0+默认用
System.Text.Json做序列化,加的是Newtonsoft.Json的[JsonProperty]特性,序列化器无法识别 - 未做全局序列化配置,部分框架默认配置优先级高于属性特性,导致特性规则不生效
具体配置方案
根据项目用的序列化器选对应方案即可,全局配置后不需要给每个属性单独加特性,所有层级的null属性(包括嵌套类)都会自动忽略。
方案1:.NET Core 3.0/.NET 5+ (默认使用System.Text.Json)
在项目的Program.cs(.NET 6+ 最小托管模型)中添加如下配置:
builder.Services.AddControllers() .AddJsonOptions(options => { // 全局序列化时忽略所有值为null的属性 options.JsonSerializerOptions.DefaultIgnoreCondition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull; });
如果是用Startup.cs的旧版本.NET Core,在ConfigureServices方法中添加相同配置即可。
如果只想给单个属性配置规则,不要混用Newtonsoft的特性,用System.Text.Json原生特性:
public class School { public Student students {get; set;} [System.Text.Json.Serialization.JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] public Teacher teachers {get; set;} }
方案2:使用Newtonsoft.Json作为序列化器的项目(含.NET Framework Web API、手动替换序列化器的.NET Core项目)
如果是.NET 6+项目,先确保已经安装了Microsoft.AspNetCore.Mvc.NewtonsoftJson包,然后在Program.cs中添加配置:
builder.Services.AddControllers() .AddNewtonsoftJson(options => { // 全局忽略null值属性 options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore; });
如果是.NET Framework Web API项目,找到App_Start/WebApiConfig.cs文件,在Register方法中添加配置:
config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
单个属性配置时,确保引用的是Newtonsoft.Json命名空间下的特性:
public class School { public Student students {get; set;} [Newtonsoft.Json.JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public Teacher teachers {get; set;} }
效果验证
配置完成后重启项目,当teachers属性为null时,接口返回结果如下,符合预期:
{ "students": { "id": "1234", "name": "Alex" } }
注意:如果配置后仍不生效,检查项目中是否存在自定义JSON格式化器、序列化过滤器重写了全局配置,导致空值规则被覆盖。
内容的提问来源于stack exchange,提问作者GOPI KRISHNAN

