Skip to content

Commit

Permalink
add new JsonIgnoreAttribute WhenWriting/WhenReading (#104562)
Browse files Browse the repository at this point in the history
* feat: add new JsonIgnoreAttribute WhenWriting/WhenReading

* remove empty line to align existing style

* test: add test case

* test: source generation test

* update test case and fix some formatting

---------

Co-authored-by: Eirik Tsarpalis <eirik.tsarpalis@gmail.com>
  • Loading branch information
WeihanLi and eiriktsarpalis authored Nov 1, 2024
1 parent 598d5f7 commit 357b09d
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 2 deletions.
8 changes: 8 additions & 0 deletions src/libraries/System.Text.Json/Common/JsonIgnoreCondition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,13 @@ public enum JsonIgnoreCondition
/// This is applied only to reference-type properties and fields.
/// </summary>
WhenWritingNull = 3,
/// <summary>
/// Property is ignored during serialization
/// </summary>
WhenWriting = 4,
/// <summary>
/// Property is ignored during deserialization
/// </summary>
WhenReading = 5,
}
}
2 changes: 2 additions & 0 deletions src/libraries/System.Text.Json/ref/System.Text.Json.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<JsonIgnoreCondition_WhenReadingWritingTestModel>(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; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<InvalidOperationException>(async() => await Serializer.SerializeWrapper(obj));
await Assert.ThrowsAsync<InvalidOperationException>(async () => await Serializer.SerializeWrapper(obj));
}

[Fact]
Expand Down Expand Up @@ -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))]
Expand All @@ -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))]
Expand Down Expand Up @@ -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))]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down

0 comments on commit 357b09d

Please sign in to comment.