diff --git a/src/libraries/System.Text.Json/Common/JsonIgnoreCondition.cs b/src/libraries/System.Text.Json/Common/JsonIgnoreCondition.cs index bea024fead644..e2fb3b97307b8 100644 --- a/src/libraries/System.Text.Json/Common/JsonIgnoreCondition.cs +++ b/src/libraries/System.Text.Json/Common/JsonIgnoreCondition.cs @@ -30,5 +30,13 @@ public enum JsonIgnoreCondition /// This is applied only to reference-type properties and fields. /// WhenWritingNull = 3, + /// + /// Property is ignored during serialization + /// + WhenWriting = 4, + /// + /// Property is ignored during deserialization + /// + WhenReading = 5, } } diff --git a/src/libraries/System.Text.Json/ref/System.Text.Json.cs b/src/libraries/System.Text.Json/ref/System.Text.Json.cs index 1e65d913f1d14..67673d875f1e0 100644 --- a/src/libraries/System.Text.Json/ref/System.Text.Json.cs +++ b/src/libraries/System.Text.Json/ref/System.Text.Json.cs @@ -1028,6 +1028,8 @@ public enum JsonIgnoreCondition Always = 1, WhenWritingDefault = 2, WhenWritingNull = 3, + WhenWriting = 4, + WhenReading = 5, } [System.AttributeUsageAttribute(System.AttributeTargets.Field | System.AttributeTargets.Property, AllowMultiple=false)] public sealed partial class JsonIncludeAttribute : System.Text.Json.Serialization.JsonAttribute diff --git a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonPropertyInfoOfT.cs b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonPropertyInfoOfT.cs index 70a8988e81fca..ed293cc4cb9ff 100644 --- a/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonPropertyInfoOfT.cs +++ b/src/libraries/System.Text.Json/src/System/Text/Json/Serialization/Metadata/JsonPropertyInfoOfT.cs @@ -429,6 +429,14 @@ private protected override void ConfigureIgnoreCondition(JsonIgnoreCondition? ig IgnoreDefaultValuesOnWrite = true; break; + case JsonIgnoreCondition.WhenWriting: + ShouldSerialize = ShouldSerializeIgnoreConditionAlways; + break; + + case JsonIgnoreCondition.WhenReading: + Set = null; + break; + default: Debug.Fail($"Unknown value of JsonIgnoreCondition '{ignoreCondition}'"); break; diff --git a/src/libraries/System.Text.Json/tests/Common/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/Common/PropertyVisibilityTests.cs index 010b6a580ed20..c619e5be4d0aa 100644 --- a/src/libraries/System.Text.Json/tests/Common/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/Common/PropertyVisibilityTests.cs @@ -2165,6 +2165,35 @@ public async Task IgnoreConditionWhenWritingDefault_WinsOver_IgnoreReadOnlyField Assert.Equal(@"{}", json); } + [Fact] + public async Task JsonIgnoreCondition_WhenWriting() + { + var options = new JsonSerializerOptions { IgnoreReadOnlyProperties = true }; + var json = await Serializer.SerializeWrapper + ( + new JsonIgnoreCondition_WhenReadingWritingTestModel { Age = 10, Name = "Mike" }, + options + ); + Assert.Equal("""{"Age":10}""", json); + } + + [Fact] + public async Task JsonIgnoreCondition_WhenReading() + { + var json = """{"Age":10, "Name":"Mike"}"""; + var model = await Serializer.DeserializeWrapper(json); + Assert.Equal("Mike", model.Name); + Assert.Equal(0, model.Age); + } + + public class JsonIgnoreCondition_WhenReadingWritingTestModel + { + [JsonIgnore(Condition = JsonIgnoreCondition.WhenReading)] + public int Age { get; set; } + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWriting)] + public string? Name { get; set; } + } + public class ClassWithReadOnlyStringProperty { public string MyString { get; } diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyVisibilityTests.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyVisibilityTests.cs index 89635a6b64b5f..21f220509ad36 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyVisibilityTests.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.SourceGeneration.Tests/Serialization/PropertyVisibilityTests.cs @@ -129,7 +129,7 @@ public override async Task HonorJsonPropertyName_PrivateGetter() Assert.Equal(MySmallEnum.AnotherValue, obj.GetProxy()); // JsonInclude for private members not supported in source gen - await Assert.ThrowsAsync(async() => await Serializer.SerializeWrapper(obj)); + await Assert.ThrowsAsync(async () => await Serializer.SerializeWrapper(obj)); } [Fact] @@ -331,7 +331,8 @@ public override async Task ClassWithIgnoredAndPrivateMembers_DoesNotIncludeIgnor [JsonSerializable(typeof(IDiamondInterfaceHierarchyWithNamingConflict.IJoinInterface), TypeInfoPropertyName = "IDiamondInterfaceHierarchyWithNamingConflictIJoinInterface")] [JsonSerializable(typeof(IDiamondInterfaceHierarchyWithNamingConflictUsingAttribute.IJoinInterface), TypeInfoPropertyName = "IDiamondInterfaceHierarchyWithNamingConflictUsingAttributeIJoinInterface")] [JsonSerializable(typeof(CollectionWithPrivateElementType))] - [JsonSerializable(typeof(DictionaryWithPrivateKeyAndValueType))][JsonSerializable(typeof(ClassWithIgnoredAndPrivateMembers))] + [JsonSerializable(typeof(DictionaryWithPrivateKeyAndValueType))] + [JsonSerializable(typeof(ClassWithIgnoredAndPrivateMembers))] [JsonSerializable(typeof(ClassWithInternalJsonIncludeProperties))] [JsonSerializable(typeof(ClassWithIgnoredAndPrivateMembers))] [JsonSerializable(typeof(ClassUsingIgnoreWhenWritingDefaultAttribute))] @@ -340,6 +341,7 @@ public override async Task ClassWithIgnoredAndPrivateMembers_DoesNotIncludeIgnor [JsonSerializable(typeof(ClassWithProperty_IgnoreConditionAlways_Ctor))] [JsonSerializable(typeof(ClassWithClassProperty_IgnoreConditionWhenWritingDefault_Ctor))] [JsonSerializable(typeof(StructWithStructProperty_IgnoreConditionWhenWritingDefault_Ctor))] + [JsonSerializable(typeof(JsonIgnoreCondition_WhenReadingWritingTestModel))] [JsonSerializable(typeof(SmallStructWithValueAndReferenceTypes))] [JsonSerializable(typeof(WrapperForClassWithIgnoredUnsupportedDictionary))] [JsonSerializable(typeof(Class1))] @@ -613,6 +615,7 @@ partial class DefaultContextWithGlobalIgnoreSetting : JsonSerializerContext; [JsonSerializable(typeof(ClassWithProperty_IgnoreConditionAlways_Ctor))] [JsonSerializable(typeof(ClassWithClassProperty_IgnoreConditionWhenWritingDefault_Ctor))] [JsonSerializable(typeof(StructWithStructProperty_IgnoreConditionWhenWritingDefault_Ctor))] + [JsonSerializable(typeof(JsonIgnoreCondition_WhenReadingWritingTestModel))] [JsonSerializable(typeof(SmallStructWithValueAndReferenceTypes))] [JsonSerializable(typeof(WrapperForClassWithIgnoredUnsupportedDictionary))] [JsonSerializable(typeof(Class1))] diff --git a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/DefaultJsonTypeInfoResolverTests.JsonPropertyInfo.cs b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/DefaultJsonTypeInfoResolverTests.JsonPropertyInfo.cs index 631be65d8f24f..4f263a7c88289 100644 --- a/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/DefaultJsonTypeInfoResolverTests.JsonPropertyInfo.cs +++ b/src/libraries/System.Text.Json/tests/System.Text.Json.Tests/Serialization/MetadataTests/DefaultJsonTypeInfoResolverTests.JsonPropertyInfo.cs @@ -908,6 +908,7 @@ public enum ModifyJsonIgnore [InlineData(JsonIgnoreCondition.Never, ModifyJsonIgnore.DontModify)] [InlineData(JsonIgnoreCondition.WhenWritingDefault, ModifyJsonIgnore.NeverSerialize)] [InlineData(JsonIgnoreCondition.WhenWritingNull, ModifyJsonIgnore.NeverSerialize)] + [InlineData(JsonIgnoreCondition.WhenWriting, ModifyJsonIgnore.NeverSerialize)] [InlineData(JsonIgnoreCondition.Never, ModifyJsonIgnore.NeverSerialize)] [InlineData(JsonIgnoreCondition.WhenWritingDefault, ModifyJsonIgnore.AlwaysSerialize)] [InlineData(JsonIgnoreCondition.WhenWritingNull, ModifyJsonIgnore.AlwaysSerialize)]