JsonIgnoreCondition.WhenWritingDefault对空字符串不生效问题求助
问题:.NET Core WebAPI 空字符串字段未被忽略的问题
我有一个.NET Core WebAPI,返回的字段里偶尔会有空字符串,为了节省带宽,我想不返回这类字段。已经配置了JsonIgnoreCondition.WhenWritingDefault,但接口还是会返回包含空字符串的字段。
实体类代码
public class Person { public int PersonId { get; set; } [DefaultValue("")] public string FirstName { get; set; } = ""; [DefaultValue("")] public string MiddleName { get; set; } = ""; [DefaultValue("")] public string LastName { get; set; } = ""; }
接口代码
[HttpGet] public string Get() { var people = new List<Person>(); people.Add(new Person() {PersonId = 1, FirstName = "Joe"}); people.Add(new Person() {PersonId = 2, MiddleName = "Fred"}); people.Add(new Person() {PersonId = 3, LastName = "Jim"}); return JsonSerializer.Serialize(people, new JsonSerializerOptions(){ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault }); }
实际返回结果
[ { "PersonId": 1, "FirstName": "Joe", "MiddleName": "", "LastName": "" }, { "PersonId": 2, "FirstName": "", "MiddleName": "Fred", "LastName": "" }, { "PersonId": 3, "FirstName": "", "MiddleName": "", "LastName": "Jim" } ]
期望返回结果
[ { "PersonId": 1, "FirstName": "Joe" }, { "PersonId": 2, "MiddleName": "Fred" }, { "PersonId": 3, "LastName": "Jim" } ]
解决方案
问题根源:JsonIgnoreCondition.WhenWritingDefault是按类型默认值判断的——string类型的默认值是null,而你代码里给字符串字段设的初始值是空字符串"",这并不属于string的默认值范畴,所以序列化器不会忽略这些空字符串字段。另外,System.Text.Json不识别[DefaultValue("")]特性,这个特性对序列化逻辑没有作用。
下面提供三种可行的解决办法:
办法1:把字符串初始值改成null(最简单)
直接修改实体类,去掉[DefaultValue("")],并将字符串字段的初始值设为null:
public class Person { public int PersonId { get; set; } public string FirstName { get; set; } public string MiddleName { get; set; } public string LastName { get; set; } }
这样当字段为null时,WhenWritingDefault就会自动忽略它们。如果你的业务逻辑里空字符串和null可以等价处理,这个方法最省事。
办法2:修改序列化配置,把空字符串视为默认值
如果必须保留空字符串作为初始值,可以通过自定义类型元数据,让序列化器把空字符串当成string类型的默认值:
[HttpGet] public string Get() { var people = new List<Person>(); people.Add(new Person() { PersonId = 1, FirstName = "Joe" }); people.Add(new Person() { PersonId = 2, MiddleName = "Fred" }); people.Add(new Person() { PersonId = 3, LastName = "Jim" }); var options = new JsonSerializerOptions { DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault }; // 注入类型元数据修改器,将string类型的默认值设为空字符串 options.TypeInfoResolver = new DefaultJsonTypeInfoResolver { Modifiers = { typeInfo => { if (typeInfo.Kind == JsonTypeInfoKind.Object) { foreach (var property in typeInfo.Properties) { if (property.PropertyType == typeof(string)) { property.DefaultValue = ""; } } } } } }; return JsonSerializer.Serialize(people, options); }
这样序列化时,所有值为空字符串的字段都会被当成默认值,从而被忽略。
办法3:在字段setter里转空字符串为null
如果需要在业务层区分空字符串和null,但序列化时要忽略空字符串,可以在字段的setter里把空字符串转为null:
public class Person { public int PersonId { get; set; } private string _firstName = ""; public string FirstName { get => _firstName; set => _firstName = string.IsNullOrEmpty(value) ? null : value; } private string _middleName = ""; public string MiddleName { get => _middleName; set => _middleName = string.IsNullOrEmpty(value) ? null : value; } private string _lastName = ""; public string LastName { get => _lastName; set => _lastName = string.IsNullOrEmpty(value) ? null : value; } }
同时保持序列化配置不变:
return JsonSerializer.Serialize(people, new JsonSerializerOptions(){ DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingDefault });
这样当设置空字符串时,字段值会被转为null,序列化时就会被忽略。
内容的提问来源于stack exchange,提问作者tempestdata
相关产品推荐
相关产品推荐

