Skip to content

Commit

Permalink
Merge pull request #30 from zcsizmadia/use-defaultjsontypeinforesolver
Browse files Browse the repository at this point in the history
Use DefaultJsonTypeInfoResolver as base
  • Loading branch information
zcsizmadia committed Aug 10, 2023
2 parents 9e6167d + 11d28d4 commit d0026a3
Show file tree
Hide file tree
Showing 4 changed files with 211 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
run: dotnet build -c Release --no-restore

- name: Test
run: dotnet test --no-restore --logger "console;verbosity=normal"
run: dotnet test -c Release --no-restore

- name: Pack (non-release)
if: github.event_name != 'release'
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<TestTargetFrameworks>netcoreapp3.1;net5.0;net6.0;net7.0</TestTargetFrameworks>
<SampleTargetFramework>net7.0</SampleTargetFramework>

<!-- Unit tests are running against EOL SDKs as well. DIsable all warnings related to EOL SDK -->
<!-- Unit tests are running against EOL SDKs as well. Disable all warnings related to EOL SDK -->
<CheckEolTargetFramework>false</CheckEolTargetFramework>
<SuppressTfmSupportBuildWarnings>true</SuppressTfmSupportBuildWarnings>
</PropertyGroup>
Expand Down
24 changes: 13 additions & 11 deletions src/ZCS.DataContractResolver/DataContractResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

namespace System.Text.Json.Serialization.Metadata
{
public class DataContractResolver : IJsonTypeInfoResolver
public class DataContractResolver : DefaultJsonTypeInfoResolver
{
private static DataContractResolver s_defaultInstance;

Expand Down Expand Up @@ -136,25 +136,27 @@ private static IEnumerable<JsonPropertyInfo> CreateDataMembers(JsonTypeInfo json

public static JsonTypeInfo GetTypeInfo(JsonTypeInfo jsonTypeInfo)
{
if (jsonTypeInfo.Kind != JsonTypeInfoKind.None)
if (jsonTypeInfo.Kind == JsonTypeInfoKind.Object)
{
jsonTypeInfo.CreateObject = () => Activator.CreateInstance(jsonTypeInfo.Type)!;

if (jsonTypeInfo.Kind == JsonTypeInfoKind.Object)
foreach (var jsonPropertyInfo in CreateDataMembers(jsonTypeInfo).OrderBy((x) => x.Order))
{
foreach (var jsonPropertyInfo in CreateDataMembers(jsonTypeInfo).OrderBy((x) => x.Order))
{
jsonTypeInfo.Properties.Add(jsonPropertyInfo);
}
jsonTypeInfo.Properties.Add(jsonPropertyInfo);
}
}

return jsonTypeInfo;
}

public JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options)
public override JsonTypeInfo GetTypeInfo(Type type, JsonSerializerOptions options)
{
JsonTypeInfo jsonTypeInfo = JsonTypeInfo.CreateJsonTypeInfo(type, options);
JsonTypeInfo jsonTypeInfo = base.GetTypeInfo(type, options);

if (jsonTypeInfo.Kind != JsonTypeInfoKind.Object)
{
return jsonTypeInfo;
}

jsonTypeInfo.Properties.Clear();

return GetTypeInfo(jsonTypeInfo);
}
Expand Down
196 changes: 196 additions & 0 deletions test/ZCS.DataContractResolver.Tests/DataContractResolverTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,31 @@

namespace ZCS.DataContractResolver.Tests
{
public enum PersonEnum
{
First,
Second,
Third,
Fourth
}

public class Person
{
public string FullName;
public int Age;
}

public class PersonWithoutDefaultConstructor
{
public PersonWithoutDefaultConstructor(string fullName, int age)
{
FullName = fullName;
Age = age;
}
public string FullName { get; }
public int Age { get; }
}

public class PersonWithNonPublicMember
{
public string FullName;
Expand Down Expand Up @@ -146,6 +165,22 @@ public class PersonWithSet
public HashSet<int> Set { get; set; }
}

[DataContract]
public class PersonWithArray
{
[DataMember(EmitDefaultValue = false, Order = 2)]
public string FullName { get; set; }

[DataMember(Order = 1)]
public int Age { get; set; }

[DataMember(EmitDefaultValue = false)]
public Person[] Friends { get; set; }

[DataMember(EmitDefaultValue = false)]
public int[] Array { get; set; }
}

[DataContract]
public class PersonContractWithIgnore
{
Expand Down Expand Up @@ -180,7 +215,74 @@ public class PersonContractWithNullable

[DataMember(EmitDefaultValue = false)]
public DateTime? LastLogin { get; set; }

[DataMember(EmitDefaultValue = false)]
public PersonWithoutDefaultConstructor BestFriend { get; set; }
}

[DataContract]
public class PersonContractWithEnum
{
[DataMember(EmitDefaultValue = false)]
public string FullName { get; set; }

[DataMember(EmitDefaultValue = false)]
public int Age { get; set; }

[DataMember]
public PersonEnum Enum { get; set; }

[DataMember]
public Dictionary<PersonEnum, string> Dict { get; set; }
}

[DataContract]
public class PersonContractWithBasicTypes
{
public byte Byte { get; set; }

public sbyte SByte { get; set; }

public short Short { get; set; }

public ushort UShort { get; set; }

public int Int { get; set; }

public uint UInt { get; set; }

public long Long { get; set; }

public ulong ULong { get; set; }

public float Float { get; set; }

public double Double { get; set; }

public decimal Decimal { get; set; }

public char Char { get; set; }
}

[DataContract]
public class Generic<T>
{
[DataMember]
public T Value { get; set; }
}

[DataContract]
public class GenericWithConstructor<T>
{
public GenericWithConstructor(T value)
{
Value = value;
}

[DataMember]
public T Value { get; private set; }
}

public class DataContractResolverTests
{
private static System.Collections.IEnumerable TestCases()
Expand All @@ -194,11 +296,84 @@ private static System.Collections.IEnumerable TestCases()

foreach (var ignoreCondition in ignoreConditions)
{
yield return new TestCaseData(ignoreCondition, false);
yield return new TestCaseData(ignoreCondition, true);

yield return new TestCaseData(ignoreCondition, 'a');
yield return new TestCaseData(ignoreCondition, (byte)1);
yield return new TestCaseData(ignoreCondition, (sbyte)-1);

yield return new TestCaseData(ignoreCondition, Int16.MinValue);
yield return new TestCaseData(ignoreCondition, Int16.MaxValue);

yield return new TestCaseData(ignoreCondition, Int32.MinValue);
yield return new TestCaseData(ignoreCondition, Int32.MaxValue);

yield return new TestCaseData(ignoreCondition, Int64.MinValue);
yield return new TestCaseData(ignoreCondition, Int64.MaxValue);

yield return new TestCaseData(ignoreCondition, UInt16.MinValue);
yield return new TestCaseData(ignoreCondition, UInt16.MaxValue);

yield return new TestCaseData(ignoreCondition, UInt32.MinValue);
yield return new TestCaseData(ignoreCondition, UInt32.MaxValue);

yield return new TestCaseData(ignoreCondition, UInt64.MinValue);
yield return new TestCaseData(ignoreCondition, UInt64.MaxValue);

yield return new TestCaseData(ignoreCondition, 1.2m);

yield return new TestCaseData(ignoreCondition, string.Empty);
yield return new TestCaseData(ignoreCondition, "Hello");

yield return new TestCaseData(ignoreCondition, default(DateTime));
yield return new TestCaseData(ignoreCondition, DateTime.Now);

yield return new TestCaseData(ignoreCondition, default(TimeSpan));
yield return new TestCaseData(ignoreCondition, TimeSpan.FromSeconds(1234567890));

yield return new TestCaseData(ignoreCondition, (1, 2));
yield return new TestCaseData(ignoreCondition, (1, "2"));
yield return new TestCaseData(ignoreCondition, ("1", "2"));

yield return new TestCaseData(ignoreCondition, new KeyValuePair<int, int>(1, 2));
yield return new TestCaseData(ignoreCondition, new KeyValuePair<int, string>(1, "2"));
yield return new TestCaseData(ignoreCondition, new KeyValuePair<string, string>("1", "2"));

yield return new TestCaseData(ignoreCondition, new List<int>());
yield return new TestCaseData(ignoreCondition, new List<int> { 0, 1, 2, 3 });
yield return new TestCaseData(ignoreCondition, new List<string> { "0", "1", "2", "3" });

yield return new TestCaseData(ignoreCondition, new int[0]);
yield return new TestCaseData(ignoreCondition, new int[] { 0, 1, 2, 3 });
yield return new TestCaseData(ignoreCondition, new string[] { "0", "1", "2", "3" });

yield return new TestCaseData(ignoreCondition, new Dictionary<int, int> { { 1, 2 }, { 3, 4 } });
yield return new TestCaseData(ignoreCondition, new Dictionary<int, string> { { 1, "2" }, { 3, "4" } });
yield return new TestCaseData(ignoreCondition, new Dictionary<string, string> { { "1", "2" }, { "3", "4" } });

yield return new TestCaseData(ignoreCondition, new HashSet<int>());
yield return new TestCaseData(ignoreCondition, new HashSet<int> { 0, 1, 2, 3 });
yield return new TestCaseData(ignoreCondition, new HashSet<string> { "0", "1", "2", "3" });

yield return new TestCaseData(ignoreCondition, new Generic<int>{ Value = 1 });
yield return new TestCaseData(ignoreCondition, new Generic<string> { Value = "1" });

yield return new TestCaseData(ignoreCondition, new GenericWithConstructor<int>(1));
yield return new TestCaseData(ignoreCondition, new GenericWithConstructor<string>("1"));

yield return new TestCaseData(ignoreCondition, PersonEnum.First);
yield return new TestCaseData(ignoreCondition, PersonEnum.Second);
yield return new TestCaseData(ignoreCondition, PersonEnum.Third);
yield return new TestCaseData(ignoreCondition, PersonEnum.Fourth);

yield return new TestCaseData(ignoreCondition, new Person());
yield return new TestCaseData(ignoreCondition, new Person() { FullName = "John Doe" });
yield return new TestCaseData(ignoreCondition, new Person() { Age = 21 });
yield return new TestCaseData(ignoreCondition, new Person() { FullName = "John Doe", Age = 21 });

yield return new TestCaseData(ignoreCondition, new PersonWithoutDefaultConstructor("John Doe", 21));

yield return new TestCaseData(ignoreCondition, new PersonWithNonPublicMember());
yield return new TestCaseData(ignoreCondition, new PersonWithNonPublicMember() { FullName = "John Doe" });

Expand Down Expand Up @@ -262,6 +437,13 @@ private static System.Collections.IEnumerable TestCases()
yield return new TestCaseData(ignoreCondition, new PersonWithSet() { FullName = "John Doe", Age = 21, Friends = new HashSet<Person> { new Person() { FullName = "John Doe", Age = 21 }, new Person() { FullName = "James Doe", Age = 22 } } });
yield return new TestCaseData(ignoreCondition, new PersonWithSet() { FullName = "John Doe", Age = 21, Set = new HashSet<int> { 0, 1, 2, 3, 4 } });

yield return new TestCaseData(ignoreCondition, new PersonWithArray());
yield return new TestCaseData(ignoreCondition, new PersonWithArray() { FullName = "John Doe" });
yield return new TestCaseData(ignoreCondition, new PersonWithArray() { Age = 21 });
yield return new TestCaseData(ignoreCondition, new PersonWithArray() { FullName = "John Doe", Age = 21 });
yield return new TestCaseData(ignoreCondition, new PersonWithArray() { FullName = "John Doe", Age = 21, Friends = new Person[] { new Person() { FullName = "John Doe", Age = 21 }, new Person() { FullName = "James Doe", Age = 22 } } });
yield return new TestCaseData(ignoreCondition, new PersonWithArray() { FullName = "John Doe", Age = 21, Array = new int[] { 0, 1, 2, 3, 4 } });

yield return new TestCaseData(ignoreCondition, new PersonContractWithIgnore());
yield return new TestCaseData(ignoreCondition, new PersonContractWithIgnore() { FullName = "John Doe" });
yield return new TestCaseData(ignoreCondition, new PersonContractWithIgnore() { Age = 21 });
Expand All @@ -278,6 +460,16 @@ private static System.Collections.IEnumerable TestCases()
yield return new TestCaseData(ignoreCondition, new PersonContractWithNullable() { Age = 21 });
yield return new TestCaseData(ignoreCondition, new PersonContractWithNullable() { FullName = "John Doe", Age = 21, LastLogin = DateTime.UtcNow });
yield return new TestCaseData(ignoreCondition, new PersonContractWithNullable() { FullName = "John Doe", Age = 21, LastLogin = DateTime.Now });
yield return new TestCaseData(ignoreCondition, new PersonContractWithNullable() { FullName = "John Doe", Age = 21, LastLogin = DateTime.Now, BestFriend = new PersonWithoutDefaultConstructor("James Doe", 20)});

yield return new TestCaseData(ignoreCondition, new PersonContractWithEnum());
yield return new TestCaseData(ignoreCondition, new PersonContractWithEnum() { FullName = "John Doe" });
yield return new TestCaseData(ignoreCondition, new PersonContractWithEnum() { Age = 21 });
yield return new TestCaseData(ignoreCondition, new PersonContractWithEnum() { FullName = "John Doe", Age = 21, Enum = PersonEnum.Second });
yield return new TestCaseData(ignoreCondition, new PersonContractWithEnum() { FullName = "John Doe", Age = 21, Enum = PersonEnum.Second, Dict = new Dictionary<PersonEnum, string>() { { PersonEnum.Third, "3"}, { PersonEnum.Fourth, "4" } } });

yield return new TestCaseData(ignoreCondition, new PersonContractWithBasicTypes());
yield return new TestCaseData(ignoreCondition, new PersonContractWithBasicTypes() { Byte = 1, SByte = -1, Short = -2, UShort = 2, Int = -3, UInt = 3, Long = -4, ULong = 4, Float = 1.2f, Double = 2.345, Decimal = 12.34m, Char = 'c' });
}
}

Expand All @@ -304,9 +496,13 @@ public void Tests<T>(System.Text.Json.Serialization.JsonIgnoreCondition ignoreCo

// Deserialize
T obj2 = System.Text.Json.JsonSerializer.Deserialize<T>(json, options);
T obj3 = JsonConvert.DeserializeObject<T>(json, newtonsoftSettings);

string jsonExpected2 = JsonConvert.SerializeObject(obj2, newtonsoftSettings);
string jsonExpected3 = JsonConvert.SerializeObject(obj3, newtonsoftSettings);

Assert.That(json, Is.EqualTo(jsonExpected2));
Assert.That(json, Is.EqualTo(jsonExpected3));
}
}
}

0 comments on commit d0026a3

Please sign in to comment.