Skip to content

Commit fcacfcd

Browse files
authored
Verify JsonSerializer support for init-only properties (#40150)
1 parent fb6cc28 commit fcacfcd

File tree

4 files changed

+117
-1
lines changed

4 files changed

+117
-1
lines changed

src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.NonPublicAccessors.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,9 @@ private class ClassWithMixedPropertyAccessors_PropertyAttributes
298298
[InlineData(typeof(ClassWithPrivateField_WithJsonIncludeProperty))]
299299
[InlineData(typeof(ClassWithInternalField_WithJsonIncludeProperty))]
300300
[InlineData(typeof(ClassWithProtectedField_WithJsonIncludeProperty))]
301+
[InlineData(typeof(ClassWithPrivate_InitOnlyProperty_WithJsonIncludeProperty))]
302+
[InlineData(typeof(ClassWithInternal_InitOnlyProperty_WithJsonIncludeProperty))]
303+
[InlineData(typeof(ClassWithProtected_InitOnlyProperty_WithJsonIncludeProperty))]
301304
public static void NonPublicProperty_WithJsonInclude_Invalid(Type type)
302305
{
303306
InvalidOperationException ex = Assert.Throws<InvalidOperationException>(() => JsonSerializer.Deserialize("", type));
@@ -350,5 +353,23 @@ private class ClassWithProtectedField_WithJsonIncludeProperty
350353
[JsonInclude]
351354
protected string MyString = null;
352355
}
356+
357+
private class ClassWithPrivate_InitOnlyProperty_WithJsonIncludeProperty
358+
{
359+
[JsonInclude]
360+
private string MyString { get; init; }
361+
}
362+
363+
private class ClassWithInternal_InitOnlyProperty_WithJsonIncludeProperty
364+
{
365+
[JsonInclude]
366+
internal string MyString { get; init; }
367+
}
368+
369+
private class ClassWithProtected_InitOnlyProperty_WithJsonIncludeProperty
370+
{
371+
[JsonInclude]
372+
protected string MyString { get; init; }
373+
}
353374
}
354375
}

src/libraries/System.Text.Json/tests/Serialization/PropertyVisibilityTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33

44
using System.Collections.Generic;
55
using System.Collections.Concurrent;
6-
using Xunit;
76
using System.Numerics;
7+
using Xunit;
88

99
namespace System.Text.Json.Serialization.Tests
1010
{
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using Xunit;
5+
6+
namespace System.Text.Json.Serialization.Tests
7+
{
8+
public static partial class PropertyVisibilityTests
9+
{
10+
[Theory]
11+
[InlineData(typeof(ClassWithInitOnlyProperty))]
12+
[InlineData(typeof(StructWithInitOnlyProperty))]
13+
public static void InitOnlyProperties_Work(Type type)
14+
{
15+
// Init-only property included by default.
16+
object obj = JsonSerializer.Deserialize(@"{""MyInt"":1}", type);
17+
Assert.Equal(1, (int)type.GetProperty("MyInt").GetValue(obj));
18+
19+
// Init-only properties can be serialized.
20+
Assert.Equal(@"{""MyInt"":1}", JsonSerializer.Serialize(obj));
21+
}
22+
23+
[Theory]
24+
[InlineData(typeof(Class_PropertyWith_PrivateInitOnlySetter))]
25+
[InlineData(typeof(Class_PropertyWith_InternalInitOnlySetter))]
26+
[InlineData(typeof(Class_PropertyWith_ProtectedInitOnlySetter))]
27+
public static void NonPublicInitOnlySetter_Without_JsonInclude_Fails(Type type)
28+
{
29+
// Non-public init-only property setter ignored.
30+
object obj = JsonSerializer.Deserialize(@"{""MyInt"":1}", type);
31+
Assert.Equal(0, (int)type.GetProperty("MyInt").GetValue(obj));
32+
33+
// Public getter can be used for serialization.
34+
Assert.Equal(@"{""MyInt"":0}", JsonSerializer.Serialize(obj));
35+
}
36+
37+
[Theory]
38+
[InlineData(typeof(Class_PropertyWith_PrivateInitOnlySetter_WithAttribute))]
39+
[InlineData(typeof(Class_PropertyWith_InternalInitOnlySetter_WithAttribute))]
40+
[InlineData(typeof(Class_PropertyWith_ProtectedInitOnlySetter_WithAttribute))]
41+
public static void NonPublicInitOnlySetter_With_JsonInclude_Works(Type type)
42+
{
43+
// Non-public init-only property setter included with [JsonInclude].
44+
object obj = JsonSerializer.Deserialize(@"{""MyInt"":1}", type);
45+
Assert.Equal(1, (int)type.GetProperty("MyInt").GetValue(obj));
46+
47+
// Init-only properties can be serialized.
48+
Assert.Equal(@"{""MyInt"":1}", JsonSerializer.Serialize(obj));
49+
}
50+
51+
public class ClassWithInitOnlyProperty
52+
{
53+
public int MyInt { get; init; }
54+
}
55+
56+
public struct StructWithInitOnlyProperty
57+
{
58+
public int MyInt { get; init; }
59+
}
60+
61+
public class Class_PropertyWith_PrivateInitOnlySetter
62+
{
63+
public int MyInt { get; private init; }
64+
}
65+
66+
public class Class_PropertyWith_InternalInitOnlySetter
67+
{
68+
public int MyInt { get; internal init; }
69+
}
70+
71+
public class Class_PropertyWith_ProtectedInitOnlySetter
72+
{
73+
public int MyInt { get; protected init; }
74+
}
75+
76+
public class Class_PropertyWith_PrivateInitOnlySetter_WithAttribute
77+
{
78+
[JsonInclude]
79+
public int MyInt { get; private init; }
80+
}
81+
82+
public class Class_PropertyWith_InternalInitOnlySetter_WithAttribute
83+
{
84+
[JsonInclude]
85+
public int MyInt { get; internal init; }
86+
}
87+
88+
public class Class_PropertyWith_ProtectedInitOnlySetter_WithAttribute
89+
{
90+
[JsonInclude]
91+
public int MyInt { get; protected init; }
92+
}
93+
}
94+
}

src/libraries/System.Text.Json/tests/System.Text.Json.Tests.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@
9999
<Compile Include="Serialization\OptionsTests.cs" />
100100
<Compile Include="Serialization\PolymorphicTests.cs" />
101101
<Compile Include="Serialization\PropertyNameTests.cs" />
102+
<Compile Include="Serialization\PropertyVisiblityTests.InitOnly.cs" />
102103
<Compile Include="Serialization\PropertyVisibilityTests.NonPublicAccessors.cs" />
103104
<Compile Include="Serialization\PropertyVisibilityTests.cs" />
104105
<Compile Include="Serialization\ReadScenarioTests.cs" />

0 commit comments

Comments
 (0)