Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ private static bool HandleNull(ref Utf8JsonReader reader, ref ReadStack state, J
}

JsonPropertyInfo propertyInfo = state.Current.JsonPropertyInfo;

if (!propertyInfo.ShouldDeserialize)
{
return false;
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understood well we should return true only if we're sure to be at the end of json object root

}

if (!propertyInfo.CanBeNull)
{
ThrowHelper.ThrowJsonException_DeserializeCannotBeNull(reader, state.PropertyPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,18 @@ private static void HandleStartObject(JsonSerializerOptions options, ref Utf8Jso
else
{
// Nested object.
Type objType = state.Current.JsonPropertyInfo.RuntimePropertyType;
state.Push();
state.Current.Initialize(objType, options);
if (!state.Current.JsonPropertyInfo.ShouldDeserialize)
{
state.Push();
state.Current.Drain = true;
return;
}
else
{
Type objType = state.Current.JsonPropertyInfo.RuntimePropertyType;
state.Push();
state.Current.Initialize(objType, options);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ private static bool HandleObject(
// A property that returns an object.
if (!obtainedValue)
{
if (!jsonPropertyInfo.ShouldSerialize)
{
// Ignore writing this property.
state.Current.NextProperty();
return true;
}
currentValue = jsonPropertyInfo.GetValueAsObject(state.Current.CurrentValue);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ internal struct ReadStackFrame
public int PropertyIndex;
public List<PropertyRef> PropertyRefCache;

// The current JSON data for a property does not match a given POCO, so ignore the property (recursively).
// The current JSON data for a property does not match a given POCO or ShouldDeserialize = false, so ignore the property (recursively).
public bool Drain;

public bool IsDictionary => JsonClassInfo.ClassType == ClassType.Dictionary;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,20 @@ public static void NoSetter()
string json = JsonSerializer.ToString(obj);
Assert.Contains(@"""MyString"":""DefaultValue""", json);
Assert.Contains(@"""MyInts"":[1,2]", json);
Assert.Contains(@"""MyProperty"":""MyComplexProperty""", json);
Assert.Contains(@"""MyInt"":42", json);

obj = JsonSerializer.Parse<ClassWithNoSetter>(@"{""MyString"":""IgnoreMe"",""MyInts"":[0]}");
obj = JsonSerializer.Parse<ClassWithNoSetter>(@"{""MyInt"": ""0"",""MyString"":""IgnoreMe"",""MyInts"":[0],""MyComplexProperty"":{""MyProperty"":""IgnoreMe""}}");
Assert.Equal("DefaultValue", obj.MyString);
Assert.Equal(2, obj.MyInts.Length);
Assert.Equal("MyComplexProperty", obj.MyComplexProperty.MyProperty);
Assert.Equal(42, obj.MyInt);

obj = JsonSerializer.Parse<ClassWithNoSetter>(@"{""MyInt"": null,""MyString"":""IgnoreMe"",""MyInts"":[0],""MyComplexProperty"":{""MyProperty"":""IgnoreMe""}}");
Assert.Equal("DefaultValue", obj.MyString);
Assert.Equal(2, obj.MyInts.Length);
Assert.Equal("MyComplexProperty", obj.MyComplexProperty.MyProperty);
Assert.Equal(42, obj.MyInt);
}

[Fact]
Expand Down Expand Up @@ -75,25 +85,58 @@ public static void JsonIgnoreAttribute()
Assert.Equal(@"MyString", obj.MyString);
Assert.Equal(@"MyStringWithIgnore", obj.MyStringWithIgnore);
Assert.Equal(2, obj.MyStringsWithIgnore.Length);
Assert.Equal(@"MyComplexPropertyWithIgnore", obj.MyComplexPropertyWithIgnore.MyProperty);

// Verify serialize.
string json = JsonSerializer.ToString(obj);
Assert.Contains(@"""MyString""", json);
Assert.DoesNotContain(@"MyStringWithIgnore", json);
Assert.DoesNotContain(@"MyStringsWithIgnore", json);
Assert.DoesNotContain(@"MyComplexPropertyWithIgnore", json);

// Verify deserialize default.
obj = JsonSerializer.Parse<ClassWithIgnoreAttributeProperty>(@"{}");
Assert.Equal(@"MyString", obj.MyString);
Assert.Equal(@"MyStringWithIgnore", obj.MyStringWithIgnore);
Assert.Equal(2, obj.MyStringsWithIgnore.Length);
Assert.Equal(@"MyComplexPropertyWithIgnore", obj.MyComplexPropertyWithIgnore.MyProperty);

// Verify deserialize ignores the json for MyStringWithIgnore and MyStringsWithIgnore.
// Verify deserialize ignores the json for MyStringWithIgnore, MyStringsWithIgnore and MyComplexPropertyWithIgnore.
obj = JsonSerializer.Parse<ClassWithIgnoreAttributeProperty>(
@"{""MyString"":""Hello"", ""MyStringWithIgnore"":""IgnoreMe"", ""MyStringsWithIgnore"":[""IgnoreMe""]}");
@"{""MyString"":""Hello"", ""MyStringWithIgnore"":""IgnoreMe"", ""MyStringsWithIgnore"":[""IgnoreMe""], ""MyComplexPropertyWithIgnore"":{""MyProperty"":""IgnoreMe""}}");
Assert.Contains(@"Hello", obj.MyString);
Assert.Equal(@"MyStringWithIgnore", obj.MyStringWithIgnore);
Assert.Equal(2, obj.MyStringsWithIgnore.Length);
Assert.Equal(@"MyComplexPropertyWithIgnore", obj.MyComplexPropertyWithIgnore.MyProperty);
}

[Fact]
public static void JsonIgnoreAttribute_NestedObject()
{
// Verify default state.
var obj = new NestedObjectWithIgnoreAttributeProperty();
Assert.Equal(@"MyString", obj.MyString);
Assert.Equal(@"MyStringNested", obj.NestedObject.MyStringNested);
Assert.Equal(@"MyStringNested2", obj.NestedObject.NestedObject2.MyStringNested2);

// Verify serialize.
string json = JsonSerializer.ToString(obj);
Assert.Contains(@"""MyString""", json);
Assert.Contains(@"""MyStringNested""", json);
Assert.DoesNotContain(@"MyStringNested2", json);

// Verify deserialize default.
obj = JsonSerializer.Parse<NestedObjectWithIgnoreAttributeProperty>(@"{}");
Assert.Equal(@"MyString", obj.MyString);
Assert.Equal(@"MyStringNested", obj.NestedObject.MyStringNested);
Assert.Equal(@"MyStringNested2", obj.NestedObject.NestedObject2.MyStringNested2);

// Verify deserialize ignores the json for NestedObject2.
obj = JsonSerializer.Parse<NestedObjectWithIgnoreAttributeProperty>(
@"{""MyString"":""Hello"",""NestedObject"":{""MyStringNested"":""HelloMyStringNested"",""NestedObject2"":{""MyStringNested2"":""IgnoreMe""}}}");
Assert.Contains(@"Hello", obj.MyString);
Assert.Contains(@"HelloMyStringNested", obj.NestedObject.MyStringNested);
Assert.Null(obj.NestedObject.NestedObject2);
}

// Todo: add tests with missing object property and missing collection property.
Expand All @@ -117,12 +160,16 @@ public class ClassWithNoSetter
{
public ClassWithNoSetter()
{
MyInt = 42;
MyString = "DefaultValue";
MyInts = new int[] { 1, 2 };
MyComplexProperty = new ComplexType() { MyProperty = "MyComplexProperty" };
}

public int MyInt { get; }
public string MyString { get; }
public int[] MyInts { get; }
public ComplexType MyComplexProperty { get; }
}

public class ClassWithNoGetter
Expand Down Expand Up @@ -178,6 +225,7 @@ public ClassWithIgnoreAttributeProperty()
MyString = "MyString";
MyStringWithIgnore = "MyStringWithIgnore";
MyStringsWithIgnore = new string[] { "1", "2" };
MyComplexPropertyWithIgnore = new ComplexType() { MyProperty = "MyComplexPropertyWithIgnore" };
}

[JsonIgnore]
Expand All @@ -187,6 +235,47 @@ public ClassWithIgnoreAttributeProperty()

[JsonIgnore]
public string[] MyStringsWithIgnore { get; set; }

[JsonIgnore]
public ComplexType MyComplexPropertyWithIgnore { get; set; }
}

public class ComplexType
{
public string MyProperty { get; set; }
}

public class NestedObjectWithIgnoreAttributeProperty
{
public NestedObjectWithIgnoreAttributeProperty()
{
MyString = "MyString";
NestedObject = new NestedObject()
{
MyStringNested = "MyStringNested",
NestedObject2 = new NestedObject2()
{
MyStringNested2 = "MyStringNested2"
}
};
}

public string MyString { get; set; }

public NestedObject NestedObject { get; set; }
}

public class NestedObject
{
public string MyStringNested { get; set; }

[JsonIgnore]
public NestedObject2 NestedObject2 { get; set; }
}

public class NestedObject2
{
public string MyStringNested2 { get; set; }
}
}
}