之前提了一个 api 建议为 JsonIgnore 添加两个扩展,WhenReading和WhenWriting,主要的一个用例是WhenReading我们的 Api Response 里有一个字段非常的大,不需要在 response 里包含,但是从 json 里反序列化时时需要地所以不能简单地直接忽略,在使用 Newtonsoft.Json 时使用ShouldSerialize约定方法在序列化的时候忽略,如果有一个WhenWriting的 ignore 选项可以比较方便地从 Newtonsoft.Json 做迁移,去年的时候 api review approved 了,之前看到有一个关联的 PR 不过后来一直没有更新,于是尝试自己提了一个 PR 以提供支持New Apinamespace System.Text.Json.Serialization;摘要:之前提了一个 api 建议为 JsonIgnore 添加两个扩展,WhenReading和WhenWriting,主要的一个用例是WhenReading我们的 Api Response 里有一个字段非常的大,不需要在 response 里包含,但是从 json
public enum JsonIgnoreCondition
{
Never,
Always,
WhenWritingDefault,
WhenWriting,
+ WhenWriting,
+ WhenReading,
}
为JsonIgnoreCondition新增了WhenWriting/WhenReading选项,在序列化和反序列化时进行忽略Sample
下面我们来看一个简单的使用示例:
sealedclassPerson{
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWriting)]
publicintId {get;set; }
publicrequiredstringName {get;set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenReading)]
publicstring? Description {get;set; }
publicoverridestringToString
{
return$"{Id}-{Name}";
}
}
varp1 =newPerson
{
Id =1
Name ="Jane"
Description ="Jane J"
};
Console.WriteLine("Person1");
Console.WriteLine(p1.ToJson);// ToJson 是一个基于 Newtonsoft.Json 的扩展方法,来方便做一些测试
varjsonP1 = JsonSerializer.Serialize(p1);
Console.WriteLine(jsonP1);
varp1Deserialized = JsonSerializer.Deserialize(jsonP1);
Console.WriteLine(p1Deserialized.ToJson);
输出结果如下:
person sample output可以看到Id因为添加了WhenWriting的的,在序列化的时候被忽略了,只有 Name 和 Description 输出了,在之后的反序列化中,因为Description添加了[JsonIgnore(Condition = JsonIgnoreCondition.WhenReading)]所以 Description 是没有更新值的,值是 又因为默认忽略了 的输出,所以最后的输出结果中我们是没有看到Description相信这个例子可以比较好的理解其用法,在测试的过程中还发现了一个有趣的事情,下面也分享一下
接下来示例用到的 model 定义如下:
sealedrecordUser(intUserId,stringUserName);
sealedrecordUser2([property:JsonIgnore(Condition = JsonIgnoreCondition.WhenWriting)]intUserId,stringUserName);
sealedrecordUser3(
[property:JsonIgnore(Condition = JsonIgnoreCondition.WhenWriting)]intUserId,
stringUserName,
[property:JsonIgnore(Condition = JsonIgnoreCondition.WhenReading)]string? Description
);
sealedrecord User4
{
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWriting)]
publicintUserId {get; init; }
publicrequiredstringUserName {get; init; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenReading)]
publicstring? Description {get;set; }
}
注意的话会发现这几个都是测试示例如下:varuser1 =newUser(1"Mike");
varuser2 =newUser2(1"Mike");
varuser3 =newUser3(1"Mike""Michael");
varuser4 =newUser4 { UserId =1, UserName ="Alice", Description ="Alice "};
Console.WriteLine("User1");
Console.WriteLine(user1.ToJson);
varjson1 = JsonSerializer.Serialize(user1);
Console.WriteLine(json1);
varuser1Deserialized = JsonSerializer.Deserialize(json1);
Console.WriteLine(user1Deserialized);
Console.WriteLine("User2");
Console.WriteLine(user2.ToJson);
varjson2 = JsonSerializer.Serialize(user2);
Console.WriteLine(json2);
varuser2Deserialized = JsonSerializer.Deserialize(json2);
Console.WriteLine(user2Deserialized);
Console.WriteLine("User3");
Console.WriteLine(user3.ToJson);
varjson3 = JsonSerializer.Serialize(user3);
Console.WriteLine(json3);
varuser3Deserialized = JsonSerializer.Deserialize(json3);
Console.WriteLine(user3Deserialized);
Console.WriteLine("User4");
Console.WriteLine(user4.ToJson);
varjson4 = JsonSerializer.Serialize(user4);
Console.WriteLine(json4);
varuser4Deserialized = JsonSerializer.Deserialize(json4);
Console.WriteLine(user4Deserialized);
输出结果如下:
User1 是没有使用 JsonIgnore attribute 的,序列化和反序列化属性都有输出和设置
User2 设置了 Id 使用
[property:JsonIgnore(Condition = JsonIgnoreCondition.WhenWriting)]UserIdUser3 设置了 Id 使用
UserId在序列化的时候被忽略了,Description[property:JsonIgnore(Condition = JsonIgnoreCondition.WhenReading)]但是从输出结果可以看出来,Description还是有值的,这一点感觉有点问题,我们设置了反序列化应该忽略,不过它是在构造器上的,不是通过属性 setter 设置的,是不是也是可以接受的呢?晚点在 GitHub 上建一个 issue 看看大佬们的想法User4 为了避免前面构造器的问题,我们使用一个普通的 property 来测试,同样的为UserId设置 [property:JsonIgnore(Condition = JsonIgnoreCondition.WhenWriting)] 并为Description设置 [property:JsonIgnore(Condition = JsonIgnoreCondition.WhenReading)] ,从输出结果可以看出此时我们的 Description 在反序列化的时候是被忽略的目前使用 Source Generator 时也有一些类似的问题,并且 Generator 处理WhenWriting时有点问题,后续会进行修复,大家感兴趣可以尝试一下哈More新的 JsonIgnoreCondition 可以比较方便地只处理属性的序列化和反序列化时忽略,大家有类似的需求的话也可以尝试下哈
References来源:opendotnet
免责声明:本站系转载,并不代表本网赞同其观点和对其真实性负责。如涉及作品内容、版权和其它问题,请在30日内与本站联系,我们将在第一时间删除内容!